refactor(core): All calls to supplyData should use a distinct context type (no-changelog) (#11421)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2024-10-28 11:37:23 +01:00
committed by GitHub
parent 04c075a46b
commit 8f5fe05a92
70 changed files with 560 additions and 308 deletions

View File

@@ -1,13 +1,13 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import { NodeOperationError, NodeConnectionType } from 'n8n-workflow';
NodeOperationError, import type {
type IExecuteFunctions, IExecuteFunctions,
type INodeExecutionData, INodeExecutionData,
type INodeType, INodeType,
type INodeTypeDescription, INodeTypeDescription,
type INodeOutputConfiguration, INodeOutputConfiguration,
type SupplyData, SupplyData,
NodeConnectionType, ISupplyDataFunctions,
} from 'n8n-workflow'; } from 'n8n-workflow';
// TODO: Add support for execute function. Got already started but got commented out // TODO: Add support for execute function. Got already started but got commented out
@@ -72,7 +72,7 @@ export const vmResolver = makeResolverFromLegacyOptions({
}); });
function getSandbox( function getSandbox(
this: IExecuteFunctions, this: IExecuteFunctions | ISupplyDataFunctions,
code: string, code: string,
options?: { addItems?: boolean; itemIndex?: number }, options?: { addItems?: boolean; itemIndex?: number },
) { ) {
@@ -354,7 +354,7 @@ export class Code implements INodeType {
} }
} }
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const code = this.getNodeParameter('code', itemIndex) as { supplyData?: { code: string } }; const code = this.getNodeParameter('code', itemIndex) as { supplyData?: { code: string } };
if (!code.supplyData?.code) { if (!code.supplyData?.code) {

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -177,7 +177,7 @@ export class DocumentBinaryInputLoader implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions): Promise<SupplyData> {
this.logger.debug('Supply Data for Binary Input Loader'); this.logger.debug('Supply Data for Binary Input Loader');
const textSplitter = (await this.getInputConnectionData( const textSplitter = (await this.getInputConnectionData(
NodeConnectionType.AiTextSplitter, NodeConnectionType.AiTextSplitter,

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -283,7 +283,7 @@ export class DocumentDefaultDataLoader implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const dataType = this.getNodeParameter('dataType', itemIndex, 'json') as 'json' | 'binary'; const dataType = this.getNodeParameter('dataType', itemIndex, 'json') as 'json' | 'binary';
const textSplitter = (await this.getInputConnectionData( const textSplitter = (await this.getInputConnectionData(
NodeConnectionType.AiTextSplitter, NodeConnectionType.AiTextSplitter,

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { GithubRepoLoader } from '@langchain/community/document_loaders/web/github'; import { GithubRepoLoader } from '@langchain/community/document_loaders/web/github';
@@ -93,7 +93,7 @@ export class DocumentGithubLoader implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
console.log('Supplying data for Github Document Loader'); console.log('Supplying data for Github Document Loader');
const repository = this.getNodeParameter('repository', itemIndex) as string; const repository = this.getNodeParameter('repository', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -79,7 +79,7 @@ export class DocumentJsonInputLoader implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions): Promise<SupplyData> {
this.logger.debug('Supply Data for JSON Input Loader'); this.logger.debug('Supply Data for JSON Input Loader');
const textSplitter = (await this.getInputConnectionData( const textSplitter = (await this.getInputConnectionData(
NodeConnectionType.AiTextSplitter, NodeConnectionType.AiTextSplitter,

View File

@@ -2,9 +2,9 @@
import { BedrockEmbeddings } from '@langchain/aws'; import { BedrockEmbeddings } from '@langchain/aws';
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -104,7 +104,7 @@ export class EmbeddingsAwsBedrock implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('aws'); const credentials = await this.getCredentials('aws');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -92,7 +92,7 @@ export class EmbeddingsAzureOpenAi implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply data for embeddings'); this.logger.debug('Supply data for embeddings');
const credentials = await this.getCredentials<{ const credentials = await this.getCredentials<{
apiKey: string; apiKey: string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { CohereEmbeddings } from '@langchain/cohere'; import { CohereEmbeddings } from '@langchain/cohere';
@@ -99,7 +99,7 @@ export class EmbeddingsCohere implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply data for embeddings Cohere'); this.logger.debug('Supply data for embeddings Cohere');
const modelName = this.getNodeParameter('modelName', itemIndex, 'embed-english-v2.0') as string; const modelName = this.getNodeParameter('modelName', itemIndex, 'embed-english-v2.0') as string;
const credentials = await this.getCredentials<{ apiKey: string }>('cohereApi'); const credentials = await this.getCredentials<{ apiKey: string }>('cohereApi');

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { GoogleGenerativeAIEmbeddings } from '@langchain/google-genai'; import { GoogleGenerativeAIEmbeddings } from '@langchain/google-genai';
@@ -116,7 +116,7 @@ export class EmbeddingsGoogleGemini implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply data for embeddings Google Gemini'); this.logger.debug('Supply data for embeddings Google Gemini');
const modelName = this.getNodeParameter( const modelName = this.getNodeParameter(
'modelName', 'modelName',

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { HuggingFaceInferenceEmbeddings } from '@langchain/community/embeddings/hf'; import { HuggingFaceInferenceEmbeddings } from '@langchain/community/embeddings/hf';
@@ -81,7 +81,7 @@ export class EmbeddingsHuggingFaceInference implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply data for embeddings HF Inference'); this.logger.debug('Supply data for embeddings HF Inference');
const model = this.getNodeParameter( const model = this.getNodeParameter(
'modelName', 'modelName',

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { MistralAIEmbeddingsParams } from '@langchain/mistralai'; import type { MistralAIEmbeddingsParams } from '@langchain/mistralai';
@@ -134,7 +134,7 @@ export class EmbeddingsMistralCloud implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('mistralCloudApi'); const credentials = await this.getCredentials('mistralCloudApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;
const options = this.getNodeParameter( const options = this.getNodeParameter(

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { OllamaEmbeddings } from '@langchain/ollama'; import { OllamaEmbeddings } from '@langchain/ollama';
@@ -44,7 +44,7 @@ export class EmbeddingsOllama implements INodeType {
properties: [getConnectionHintNoticeField([NodeConnectionType.AiVectorStore]), ollamaModel], properties: [getConnectionHintNoticeField([NodeConnectionType.AiVectorStore]), ollamaModel],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply data for embeddings Ollama'); this.logger.debug('Supply data for embeddings Ollama');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;
const credentials = await this.getCredentials('ollamaApi'); const credentials = await this.getCredentials('ollamaApi');

View File

@@ -1,10 +1,10 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type SupplyData, type SupplyData,
type ISupplyDataFunctions,
type INodeProperties, type INodeProperties,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -170,7 +170,7 @@ export class EmbeddingsOpenAi implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply data for embeddings'); this.logger.debug('Supply data for embeddings');
const credentials = await this.getCredentials('openAiApi'); const credentials = await this.getCredentials('openAiApi');

View File

@@ -3,7 +3,7 @@ import {
NodeConnectionType, NodeConnectionType,
type INodePropertyOptions, type INodePropertyOptions,
type INodeProperties, type INodeProperties,
type IExecuteFunctions, type ISupplyDataFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type SupplyData, type SupplyData,
@@ -175,7 +175,7 @@ export class LmChatAnthropic implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('anthropicApi'); const credentials = await this.getCredentials('anthropicApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -52,7 +52,7 @@ export class LmChatOllama implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('ollamaApi'); const credentials = await this.getCredentials('ollamaApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
type JsonObject, type JsonObject,
NodeApiError, NodeApiError,
@@ -242,7 +242,7 @@ export class LmChatOpenAi implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('openAiApi'); const credentials = await this.getCredentials('openAiApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -90,7 +90,7 @@ export class LmCohere implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('cohereApi'); const credentials = await this.getCredentials('cohereApi');
const options = this.getNodeParameter('options', itemIndex, {}) as object; const options = this.getNodeParameter('options', itemIndex, {}) as object;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -51,7 +51,7 @@ export class LmOllama implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('ollamaApi'); const credentials = await this.getCredentials('ollamaApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { NodeConnectionType } from 'n8n-workflow'; import { NodeConnectionType } from 'n8n-workflow';
import type { import type {
IExecuteFunctions,
INodeType, INodeType,
INodeTypeDescription, INodeTypeDescription,
ISupplyDataFunctions,
SupplyData, SupplyData,
ILoadOptionsFunctions, ILoadOptionsFunctions,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -229,7 +229,7 @@ export class LmOpenAi implements INodeType {
}, },
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('openAiApi'); const credentials = await this.getCredentials('openAiApi');
const modelName = this.getNodeParameter('model', itemIndex, '', { const modelName = this.getNodeParameter('model', itemIndex, '', {

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -132,7 +132,7 @@ export class LmOpenHuggingFaceInference implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('huggingFaceApi'); const credentials = await this.getCredentials('huggingFaceApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -2,9 +2,9 @@
import { ChatBedrockConverse } from '@langchain/aws'; import { ChatBedrockConverse } from '@langchain/aws';
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -132,7 +132,7 @@ export class LmChatAwsBedrock implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('aws'); const credentials = await this.getCredentials('aws');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;
const options = this.getNodeParameter('options', itemIndex, {}) as { const options = this.getNodeParameter('options', itemIndex, {}) as {

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -162,7 +162,7 @@ export class LmChatAzureOpenAi implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials<{ const credentials = await this.getCredentials<{
apiKey: string; apiKey: string;
resourceName: string; resourceName: string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { ChatGoogleGenerativeAI } from '@langchain/google-genai'; import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
@@ -113,7 +113,7 @@ export class LmChatGoogleGemini implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('googlePalmApi'); const credentials = await this.getCredentials('googlePalmApi');
const modelName = this.getNodeParameter('modelName', itemIndex) as string; const modelName = this.getNodeParameter('modelName', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
type ILoadOptionsFunctions, type ILoadOptionsFunctions,
type JsonObject, type JsonObject,
@@ -124,7 +124,7 @@ export class LmChatGoogleVertex implements INodeType {
}, },
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('googleApi'); const credentials = await this.getCredentials('googleApi');
const privateKey = formatPrivateKey(credentials.privateKey as string); const privateKey = formatPrivateKey(credentials.privateKey as string);
const email = (credentials.email as string).trim(); const email = (credentials.email as string).trim();

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -129,7 +129,7 @@ export class LmChatGroq implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('groqApi'); const credentials = await this.getCredentials('groqApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -172,7 +172,7 @@ export class LmChatMistralCloud implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('mistralCloudApi'); const credentials = await this.getCredentials('mistralCloudApi');
const modelName = this.getNodeParameter('model', itemIndex) as string; const modelName = this.getNodeParameter('model', itemIndex) as string;

View File

@@ -7,7 +7,7 @@ import type {
SerializedSecret, SerializedSecret,
} from '@langchain/core/load/serializable'; } from '@langchain/core/load/serializable';
import type { LLMResult } from '@langchain/core/outputs'; import type { LLMResult } from '@langchain/core/outputs';
import type { IDataObject, IExecuteFunctions } from 'n8n-workflow'; import type { IDataObject, ISupplyDataFunctions } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow'; import { NodeConnectionType } from 'n8n-workflow';
import { pick } from 'lodash'; import { pick } from 'lodash';
import type { BaseMessage } from '@langchain/core/messages'; import type { BaseMessage } from '@langchain/core/messages';
@@ -30,8 +30,6 @@ const TIKTOKEN_ESTIMATE_MODEL = 'gpt-4o';
export class N8nLlmTracing extends BaseCallbackHandler { export class N8nLlmTracing extends BaseCallbackHandler {
name = 'N8nLlmTracing'; name = 'N8nLlmTracing';
executionFunctions: IExecuteFunctions;
connectionType = NodeConnectionType.AiLanguageModel; connectionType = NodeConnectionType.AiLanguageModel;
promptTokensEstimate = 0; promptTokensEstimate = 0;
@@ -61,11 +59,10 @@ export class N8nLlmTracing extends BaseCallbackHandler {
}; };
constructor( constructor(
executionFunctions: IExecuteFunctions, private executionFunctions: ISupplyDataFunctions,
options?: { tokensUsageParser: TokensUsageParser }, options?: { tokensUsageParser: TokensUsageParser },
) { ) {
super(); super();
this.executionFunctions = executionFunctions;
this.options = { ...this.options, ...options }; this.options = { ...this.options, ...options };
} }
@@ -138,7 +135,7 @@ export class N8nLlmTracing extends BaseCallbackHandler {
this.executionFunctions.addOutputData(this.connectionType, runDetails.index, [ this.executionFunctions.addOutputData(this.connectionType, runDetails.index, [
[{ json: { ...response } }], [{ json: { ...response } }],
]); ]);
void logAiEvent(this.executionFunctions, 'ai-llm-generated-output', { logAiEvent(this.executionFunctions, 'ai-llm-generated-output', {
messages: parsedMessages, messages: parsedMessages,
options: runDetails.options, options: runDetails.options,
response, response,
@@ -186,7 +183,7 @@ export class N8nLlmTracing extends BaseCallbackHandler {
}); });
} }
void logAiEvent(this.executionFunctions, 'ai-llm-errored', { logAiEvent(this.executionFunctions, 'ai-llm-errored', {
error: Object.keys(error).length === 0 ? error.toString() : error, error: Object.keys(error).length === 0 ? error.toString() : error,
runId, runId,
parentRunId, parentRunId,

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { BufferWindowMemoryInput } from 'langchain/memory'; import type { BufferWindowMemoryInput } from 'langchain/memory';
@@ -134,7 +134,7 @@ export class MemoryBufferWindow implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const contextWindowLength = this.getNodeParameter('contextWindowLength', itemIndex) as number; const contextWindowLength = this.getNodeParameter('contextWindowLength', itemIndex) as number;
const workflowId = this.getWorkflow().id; const workflowId = this.getWorkflow().id;
const memoryInstance = MemoryChatBufferSingleton.getInstance(); const memoryInstance = MemoryChatBufferSingleton.getInstance();

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -86,7 +86,7 @@ export class MemoryMotorhead implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('motorheadApi'); const credentials = await this.getCredentials('motorheadApi');
const nodeVersion = this.getNode().typeVersion; const nodeVersion = this.getNode().typeVersion;

View File

@@ -1,5 +1,10 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import type { IExecuteFunctions, INodeType, INodeTypeDescription, SupplyData } from 'n8n-workflow'; import type {
ISupplyDataFunctions,
INodeType,
INodeTypeDescription,
SupplyData,
} from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow'; import { NodeConnectionType } from 'n8n-workflow';
import { BufferMemory, BufferWindowMemory } from 'langchain/memory'; import { BufferMemory, BufferWindowMemory } from 'langchain/memory';
import { PostgresChatMessageHistory } from '@langchain/community/stores/message/postgres'; import { PostgresChatMessageHistory } from '@langchain/community/stores/message/postgres';
@@ -73,7 +78,7 @@ export class MemoryPostgresChat implements INodeType {
}, },
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres'); const credentials = await this.getCredentials<PostgresNodeCredentials>('postgres');
const tableName = this.getNodeParameter('tableName', itemIndex, 'n8n_chat_histories') as string; const tableName = this.getNodeParameter('tableName', itemIndex, 'n8n_chat_histories') as string;
const sessionId = getSessionId(this, itemIndex); const sessionId = getSessionId(this, itemIndex);

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeOperationError, NodeOperationError,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
NodeConnectionType, NodeConnectionType,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -102,7 +102,7 @@ export class MemoryRedisChat implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('redis'); const credentials = await this.getCredentials('redis');
const nodeVersion = this.getNode().typeVersion; const nodeVersion = this.getNode().typeVersion;

View File

@@ -1,6 +1,11 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { NodeConnectionType, NodeOperationError } from 'n8n-workflow'; import { NodeConnectionType, NodeOperationError } from 'n8n-workflow';
import type { IExecuteFunctions, INodeType, INodeTypeDescription, SupplyData } from 'n8n-workflow'; import type {
ISupplyDataFunctions,
INodeType,
INodeTypeDescription,
SupplyData,
} from 'n8n-workflow';
import { XataChatMessageHistory } from '@langchain/community/stores/message/xata'; import { XataChatMessageHistory } from '@langchain/community/stores/message/xata';
import { BufferMemory, BufferWindowMemory } from 'langchain/memory'; import { BufferMemory, BufferWindowMemory } from 'langchain/memory';
import { BaseClient } from '@xata.io/client'; import { BaseClient } from '@xata.io/client';
@@ -88,7 +93,7 @@ export class MemoryXata implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('xataApi'); const credentials = await this.getCredentials('xataApi');
const nodeVersion = this.getNode().typeVersion; const nodeVersion = this.getNode().typeVersion;

View File

@@ -1,7 +1,7 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions, type ISupplyDataFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type SupplyData, type SupplyData,
@@ -103,7 +103,7 @@ export class MemoryZep implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials<{ const credentials = await this.getCredentials<{
apiKey?: string; apiKey?: string;
apiUrl?: string; apiUrl?: string;

View File

@@ -1,6 +1,11 @@
import type { BaseLanguageModel } from '@langchain/core/language_models/base'; import type { BaseLanguageModel } from '@langchain/core/language_models/base';
import { NodeConnectionType } from 'n8n-workflow'; import { NodeConnectionType } from 'n8n-workflow';
import type { IExecuteFunctions, INodeType, INodeTypeDescription, SupplyData } from 'n8n-workflow'; import type {
ISupplyDataFunctions,
INodeType,
INodeTypeDescription,
SupplyData,
} from 'n8n-workflow';
import { import {
N8nOutputFixingParser, N8nOutputFixingParser,
@@ -63,7 +68,7 @@ export class OutputParserAutofixing implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const model = (await this.getInputConnectionData( const model = (await this.getInputConnectionData(
NodeConnectionType.AiLanguageModel, NodeConnectionType.AiLanguageModel,
itemIndex, itemIndex,

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -80,7 +80,7 @@ export class OutputParserItemList implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const options = this.getNodeParameter('options', itemIndex, {}) as { const options = this.getNodeParameter('options', itemIndex, {}) as {
numberOfItems?: number; numberOfItems?: number;
separator?: string; separator?: string;

View File

@@ -1,9 +1,9 @@
import type { JSONSchema7 } from 'json-schema'; import type { JSONSchema7 } from 'json-schema';
import { import {
jsonParse, jsonParse,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
NodeOperationError, NodeOperationError,
NodeConnectionType, NodeConnectionType,
@@ -122,7 +122,7 @@ export class OutputParserStructured implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const schemaType = this.getNodeParameter('schemaType', itemIndex, '') as 'fromJson' | 'manual'; const schemaType = this.getNodeParameter('schemaType', itemIndex, '') as 'fromJson' | 'manual';
// We initialize these even though one of them will always be empty // We initialize these even though one of them will always be empty
// it makes it easer to navigate the ternary operator // it makes it easer to navigate the ternary operator

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -63,7 +63,7 @@ export class RetrieverContextualCompression implements INodeType {
properties: [], properties: [],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supplying data for Contextual Compression Retriever'); this.logger.debug('Supplying data for Contextual Compression Retriever');
const model = (await this.getInputConnectionData( const model = (await this.getInputConnectionData(

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -82,7 +82,7 @@ export class RetrieverMultiQuery implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supplying data for MultiQuery Retriever'); this.logger.debug('Supplying data for MultiQuery Retriever');
const options = this.getNodeParameter('options', itemIndex, {}) as { queryCount?: number }; const options = this.getNodeParameter('options', itemIndex, {}) as { queryCount?: number };

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { VectorStore } from '@langchain/core/vectorstores'; import type { VectorStore } from '@langchain/core/vectorstores';
@@ -56,7 +56,7 @@ export class RetrieverVectorStore implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supplying data for Vector Store Retriever'); this.logger.debug('Supplying data for Vector Store Retriever');
const topK = this.getNodeParameter('topK', itemIndex, 4) as number; const topK = this.getNodeParameter('topK', itemIndex, 4) as number;

View File

@@ -5,7 +5,7 @@ import type {
IExecuteWorkflowInfo, IExecuteWorkflowInfo,
INodeExecutionData, INodeExecutionData,
IWorkflowBase, IWorkflowBase,
IExecuteFunctions, ISupplyDataFunctions,
INodeType, INodeType,
INodeTypeDescription, INodeTypeDescription,
SupplyData, SupplyData,
@@ -292,15 +292,15 @@ export class RetrieverWorkflow implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
class WorkflowRetriever extends BaseRetriever { class WorkflowRetriever extends BaseRetriever {
lc_namespace = ['n8n-nodes-langchain', 'retrievers', 'workflow']; lc_namespace = ['n8n-nodes-langchain', 'retrievers', 'workflow'];
executeFunctions: IExecuteFunctions; constructor(
private executeFunctions: ISupplyDataFunctions,
constructor(executeFunctions: IExecuteFunctions, fields: BaseRetrieverInput) { fields: BaseRetrieverInput,
) {
super(fields); super(fields);
this.executeFunctions = executeFunctions;
} }
async _getRelevantDocuments( async _getRelevantDocuments(

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { CharacterTextSplitterParams } from '@langchain/textsplitters'; import type { CharacterTextSplitterParams } from '@langchain/textsplitters';
@@ -63,7 +63,7 @@ export class TextSplitterCharacterTextSplitter implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply Data for Text Splitter'); this.logger.debug('Supply Data for Text Splitter');
const separator = this.getNodeParameter('separator', itemIndex) as string; const separator = this.getNodeParameter('separator', itemIndex) as string;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { import type {
@@ -94,7 +94,7 @@ export class TextSplitterRecursiveCharacterTextSplitter implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply Data for Text Splitter'); this.logger.debug('Supply Data for Text Splitter');
const chunkSize = this.getNodeParameter('chunkSize', itemIndex) as number; const chunkSize = this.getNodeParameter('chunkSize', itemIndex) as number;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { TokenTextSplitter } from '@langchain/textsplitters'; import { TokenTextSplitter } from '@langchain/textsplitters';
@@ -56,7 +56,7 @@ export class TextSplitterTokenSplitter implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply Data for Text Splitter'); this.logger.debug('Supply Data for Text Splitter');
const chunkSize = this.getNodeParameter('chunkSize', itemIndex) as number; const chunkSize = this.getNodeParameter('chunkSize', itemIndex) as number;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { Calculator } from '@langchain/community/tools/calculator'; import { Calculator } from '@langchain/community/tools/calculator';
@@ -43,7 +43,7 @@ export class ToolCalculator implements INodeType {
properties: [getConnectionHintNoticeField([NodeConnectionType.AiAgent])], properties: [getConnectionHintNoticeField([NodeConnectionType.AiAgent])],
}; };
async supplyData(this: IExecuteFunctions): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions): Promise<SupplyData> {
return { return {
response: logWrapper(new Calculator(), this), response: logWrapper(new Calculator(), this),
}; };

View File

@@ -6,9 +6,9 @@ import { PythonSandbox } from 'n8n-nodes-base/dist/nodes/Code/PythonSandbox';
import type { Sandbox } from 'n8n-nodes-base/dist/nodes/Code/Sandbox'; import type { Sandbox } from 'n8n-nodes-base/dist/nodes/Code/Sandbox';
import { getSandboxContext } from 'n8n-nodes-base/dist/nodes/Code/Sandbox'; import { getSandboxContext } from 'n8n-nodes-base/dist/nodes/Code/Sandbox';
import type { import type {
IExecuteFunctions,
INodeType, INodeType,
INodeTypeDescription, INodeTypeDescription,
ISupplyDataFunctions,
SupplyData, SupplyData,
ExecutionError, ExecutionError,
IDataObject, IDataObject,
@@ -175,7 +175,7 @@ export class ToolCode implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const node = this.getNode(); const node = this.getNode();
const workflowMode = this.getMode(); const workflowMode = this.getMode();

View File

@@ -1,8 +1,8 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import type { import type {
IExecuteFunctions,
INodeType, INodeType,
INodeTypeDescription, INodeTypeDescription,
ISupplyDataFunctions,
SupplyData, SupplyData,
IHttpRequestMethods, IHttpRequestMethods,
IHttpRequestOptions, IHttpRequestOptions,
@@ -250,7 +250,7 @@ export class ToolHttpRequest implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const name = this.getNode().name.replace(/ /g, '_'); const name = this.getNode().name.replace(/ /g, '_');
try { try {
tryToParseAlphanumericString(name); tryToParseAlphanumericString(name);

View File

@@ -8,12 +8,12 @@ import unset from 'lodash/unset';
import * as mime from 'mime-types'; import * as mime from 'mime-types';
import { getOAuth2AdditionalParameters } from 'n8n-nodes-base/dist/nodes/HttpRequest/GenericFunctions'; import { getOAuth2AdditionalParameters } from 'n8n-nodes-base/dist/nodes/HttpRequest/GenericFunctions';
import type { import type {
IExecuteFunctions,
IDataObject, IDataObject,
IHttpRequestOptions, IHttpRequestOptions,
IRequestOptionsSimplified, IRequestOptionsSimplified,
ExecutionError, ExecutionError,
NodeApiError, NodeApiError,
ISupplyDataFunctions,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { NodeConnectionType, NodeOperationError, jsonParse } from 'n8n-workflow'; import { NodeConnectionType, NodeOperationError, jsonParse } from 'n8n-workflow';
import { z } from 'zod'; import { z } from 'zod';
@@ -28,7 +28,7 @@ import type {
} from './interfaces'; } from './interfaces';
import type { DynamicZodObject } from '../../../types/zod.types'; import type { DynamicZodObject } from '../../../types/zod.types';
const genericCredentialRequest = async (ctx: IExecuteFunctions, itemIndex: number) => { const genericCredentialRequest = async (ctx: ISupplyDataFunctions, itemIndex: number) => {
const genericType = ctx.getNodeParameter('genericAuthType', itemIndex) as string; const genericType = ctx.getNodeParameter('genericAuthType', itemIndex) as string;
if (genericType === 'httpBasicAuth' || genericType === 'httpDigestAuth') { if (genericType === 'httpBasicAuth' || genericType === 'httpDigestAuth') {
@@ -104,7 +104,7 @@ const genericCredentialRequest = async (ctx: IExecuteFunctions, itemIndex: numbe
}); });
}; };
const predefinedCredentialRequest = async (ctx: IExecuteFunctions, itemIndex: number) => { const predefinedCredentialRequest = async (ctx: ISupplyDataFunctions, itemIndex: number) => {
const predefinedType = ctx.getNodeParameter('nodeCredentialType', itemIndex) as string; const predefinedType = ctx.getNodeParameter('nodeCredentialType', itemIndex) as string;
const additionalOptions = getOAuth2AdditionalParameters(predefinedType); const additionalOptions = getOAuth2AdditionalParameters(predefinedType);
@@ -119,7 +119,7 @@ const predefinedCredentialRequest = async (ctx: IExecuteFunctions, itemIndex: nu
}; };
export const configureHttpRequestFunction = async ( export const configureHttpRequestFunction = async (
ctx: IExecuteFunctions, ctx: ISupplyDataFunctions,
credentialsType: 'predefinedCredentialType' | 'genericCredentialType' | 'none', credentialsType: 'predefinedCredentialType' | 'genericCredentialType' | 'none',
itemIndex: number, itemIndex: number,
) => { ) => {
@@ -146,7 +146,7 @@ const defaultOptimizer = <T>(response: T) => {
return String(response); return String(response);
}; };
const htmlOptimizer = (ctx: IExecuteFunctions, itemIndex: number, maxLength: number) => { const htmlOptimizer = (ctx: ISupplyDataFunctions, itemIndex: number, maxLength: number) => {
const cssSelector = ctx.getNodeParameter('cssSelector', itemIndex, '') as string; const cssSelector = ctx.getNodeParameter('cssSelector', itemIndex, '') as string;
const onlyContent = ctx.getNodeParameter('onlyContent', itemIndex, false) as boolean; const onlyContent = ctx.getNodeParameter('onlyContent', itemIndex, false) as boolean;
let elementsToOmit: string[] = []; let elementsToOmit: string[] = [];
@@ -214,7 +214,7 @@ const htmlOptimizer = (ctx: IExecuteFunctions, itemIndex: number, maxLength: num
}; };
}; };
const textOptimizer = (ctx: IExecuteFunctions, itemIndex: number, maxLength: number) => { const textOptimizer = (ctx: ISupplyDataFunctions, itemIndex: number, maxLength: number) => {
return (response: string | IDataObject) => { return (response: string | IDataObject) => {
if (typeof response === 'object') { if (typeof response === 'object') {
try { try {
@@ -245,7 +245,7 @@ const textOptimizer = (ctx: IExecuteFunctions, itemIndex: number, maxLength: num
}; };
}; };
const jsonOptimizer = (ctx: IExecuteFunctions, itemIndex: number) => { const jsonOptimizer = (ctx: ISupplyDataFunctions, itemIndex: number) => {
return (response: string): string => { return (response: string): string => {
let responseData: IDataObject | IDataObject[] | string = response; let responseData: IDataObject | IDataObject[] | string = response;
@@ -324,7 +324,7 @@ const jsonOptimizer = (ctx: IExecuteFunctions, itemIndex: number) => {
}; };
}; };
export const configureResponseOptimizer = (ctx: IExecuteFunctions, itemIndex: number) => { export const configureResponseOptimizer = (ctx: ISupplyDataFunctions, itemIndex: number) => {
const optimizeResponse = ctx.getNodeParameter('optimizeResponse', itemIndex, false) as boolean; const optimizeResponse = ctx.getNodeParameter('optimizeResponse', itemIndex, false) as boolean;
if (optimizeResponse) { if (optimizeResponse) {
@@ -469,7 +469,7 @@ const MODEL_INPUT_DESCRIPTION = {
}; };
export const updateParametersAndOptions = (options: { export const updateParametersAndOptions = (options: {
ctx: IExecuteFunctions; ctx: ISupplyDataFunctions;
itemIndex: number; itemIndex: number;
toolParameters: ToolParameter[]; toolParameters: ToolParameter[];
placeholdersDefinitions: PlaceholderDefinition[]; placeholdersDefinitions: PlaceholderDefinition[];
@@ -558,7 +558,7 @@ export const prepareToolDescription = (
}; };
export const configureToolFunction = ( export const configureToolFunction = (
ctx: IExecuteFunctions, ctx: ISupplyDataFunctions,
itemIndex: number, itemIndex: number,
toolParameters: ToolParameter[], toolParameters: ToolParameter[],
requestOptions: IHttpRequestOptions, requestOptions: IHttpRequestOptions,

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { SerpAPI } from '@langchain/community/tools/serpapi'; import { SerpAPI } from '@langchain/community/tools/serpapi';
@@ -113,7 +113,7 @@ export class ToolSerpApi implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials('serpApi'); const credentials = await this.getCredentials('serpApi');
const options = this.getNodeParameter('options', itemIndex) as object; const options = this.getNodeParameter('options', itemIndex) as object;

View File

@@ -1,4 +1,9 @@
import type { IExecuteFunctions, INodeType, INodeTypeDescription, SupplyData } from 'n8n-workflow'; import type {
INodeType,
INodeTypeDescription,
ISupplyDataFunctions,
SupplyData,
} from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow'; import { NodeConnectionType } from 'n8n-workflow';
import { VectorStoreQATool } from 'langchain/tools'; import { VectorStoreQATool } from 'langchain/tools';
@@ -82,7 +87,7 @@ export class ToolVectorStore implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const name = this.getNodeParameter('name', itemIndex) as string; const name = this.getNodeParameter('name', itemIndex) as string;
const toolDescription = this.getNodeParameter('description', itemIndex) as string; const toolDescription = this.getNodeParameter('description', itemIndex) as string;
const topK = this.getNodeParameter('topK', itemIndex, 4) as number; const topK = this.getNodeParameter('topK', itemIndex, 4) as number;

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { WikipediaQueryRun } from '@langchain/community/tools/wikipedia_query_run'; import { WikipediaQueryRun } from '@langchain/community/tools/wikipedia_query_run';
@@ -43,7 +43,7 @@ export class ToolWikipedia implements INodeType {
properties: [getConnectionHintNoticeField([NodeConnectionType.AiAgent])], properties: [getConnectionHintNoticeField([NodeConnectionType.AiAgent])],
}; };
async supplyData(this: IExecuteFunctions): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions): Promise<SupplyData> {
const WikiTool = new WikipediaQueryRun(); const WikiTool = new WikipediaQueryRun();
WikiTool.description = WikiTool.description =

View File

@@ -1,9 +1,9 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { WolframAlphaTool } from '@langchain/community/tools/wolframalpha'; import { WolframAlphaTool } from '@langchain/community/tools/wolframalpha';
@@ -49,7 +49,7 @@ export class ToolWolframAlpha implements INodeType {
properties: [getConnectionHintNoticeField([NodeConnectionType.AiAgent])], properties: [getConnectionHintNoticeField([NodeConnectionType.AiAgent])],
}; };
async supplyData(this: IExecuteFunctions): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions): Promise<SupplyData> {
const credentials = await this.getCredentials('wolframAlphaApi'); const credentials = await this.getCredentials('wolframAlphaApi');
return { return {

View File

@@ -6,12 +6,12 @@ import isObject from 'lodash/isObject';
import type { SetField, SetNodeOptions } from 'n8n-nodes-base/dist/nodes/Set/v2/helpers/interfaces'; import type { SetField, SetNodeOptions } from 'n8n-nodes-base/dist/nodes/Set/v2/helpers/interfaces';
import * as manual from 'n8n-nodes-base/dist/nodes/Set/v2/manual.mode'; import * as manual from 'n8n-nodes-base/dist/nodes/Set/v2/manual.mode';
import type { import type {
IExecuteFunctions,
IExecuteWorkflowInfo, IExecuteWorkflowInfo,
INodeExecutionData, INodeExecutionData,
INodeType, INodeType,
INodeTypeDescription, INodeTypeDescription,
IWorkflowBase, IWorkflowBase,
ISupplyDataFunctions,
SupplyData, SupplyData,
ExecutionError, ExecutionError,
IDataObject, IDataObject,
@@ -357,7 +357,7 @@ export class ToolWorkflow implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const name = this.getNodeParameter('name', itemIndex) as string; const name = this.getNodeParameter('name', itemIndex) as string;
const description = this.getNodeParameter('description', itemIndex) as string; const description = this.getNodeParameter('description', itemIndex) as string;

View File

@@ -1,10 +1,10 @@
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ /* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import { import {
NodeConnectionType, NodeConnectionType,
type SupplyData,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { Embeddings } from '@langchain/core/embeddings'; import type { Embeddings } from '@langchain/core/embeddings';
import { MemoryVectorStoreManager } from '../shared/MemoryVectorStoreManager'; import { MemoryVectorStoreManager } from '../shared/MemoryVectorStoreManager';
@@ -59,7 +59,7 @@ export class VectorStoreInMemoryLoad implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const embeddings = (await this.getInputConnectionData( const embeddings = (await this.getInputConnectionData(
NodeConnectionType.AiEmbedding, NodeConnectionType.AiEmbedding,
itemIndex, itemIndex,

View File

@@ -1,8 +1,8 @@
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { PineconeStoreParams } from '@langchain/pinecone'; import type { PineconeStoreParams } from '@langchain/pinecone';
@@ -84,7 +84,7 @@ export class VectorStorePineconeLoad implements INodeType {
}, },
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supplying data for Pinecone Load Vector Store'); this.logger.debug('Supplying data for Pinecone Load Vector Store');
const namespace = this.getNodeParameter('pineconeNamespace', itemIndex) as string; const namespace = this.getNodeParameter('pineconeNamespace', itemIndex) as string;

View File

@@ -1,7 +1,7 @@
import { import {
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
NodeConnectionType, NodeConnectionType,
} from 'n8n-workflow'; } from 'n8n-workflow';
@@ -81,7 +81,7 @@ export class VectorStoreSupabaseLoad implements INodeType {
methods = { listSearch: { supabaseTableNameSearch } }; methods = { listSearch: { supabaseTableNameSearch } };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supply Supabase Load Vector Store'); this.logger.debug('Supply Supabase Load Vector Store');
const tableName = this.getNodeParameter('tableName', itemIndex, '', { const tableName = this.getNodeParameter('tableName', itemIndex, '', {

View File

@@ -1,8 +1,8 @@
import { import {
NodeConnectionType, NodeConnectionType,
type IExecuteFunctions,
type INodeType, type INodeType,
type INodeTypeDescription, type INodeTypeDescription,
type ISupplyDataFunctions,
type SupplyData, type SupplyData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { IZepConfig } from '@langchain/community/vectorstores/zep'; import type { IZepConfig } from '@langchain/community/vectorstores/zep';
@@ -83,7 +83,7 @@ export class VectorStoreZepLoad implements INodeType {
], ],
}; };
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
this.logger.debug('Supplying data for Zep Load Vector Store'); this.logger.debug('Supplying data for Zep Load Vector Store');
const collectionName = this.getNodeParameter('collectionName', itemIndex) as string; const collectionName = this.getNodeParameter('collectionName', itemIndex) as string;

View File

@@ -7,11 +7,8 @@ export class MemoryVectorStoreManager {
private vectorStoreBuffer: Map<string, MemoryVectorStore>; private vectorStoreBuffer: Map<string, MemoryVectorStore>;
private embeddings: Embeddings; private constructor(private embeddings: Embeddings) {
private constructor(embeddings: Embeddings) {
this.vectorStoreBuffer = new Map(); this.vectorStoreBuffer = new Map();
this.embeddings = embeddings;
} }
public static getInstance(embeddings: Embeddings): MemoryVectorStoreManager { public static getInstance(embeddings: Embeddings): MemoryVectorStoreManager {

View File

@@ -5,12 +5,13 @@ import type { Embeddings } from '@langchain/core/embeddings';
import type { VectorStore } from '@langchain/core/vectorstores'; import type { VectorStore } from '@langchain/core/vectorstores';
import { NodeConnectionType, NodeOperationError } from 'n8n-workflow'; import { NodeConnectionType, NodeOperationError } from 'n8n-workflow';
import type { import type {
IExecuteFunctions,
INodeCredentialDescription, INodeCredentialDescription,
INodeProperties, INodeProperties,
INodeExecutionData, INodeExecutionData,
IExecuteFunctions,
INodeTypeDescription, INodeTypeDescription,
SupplyData, SupplyData,
ISupplyDataFunctions,
INodeType, INodeType,
ILoadOptionsFunctions, ILoadOptionsFunctions,
INodeListSearchResult, INodeListSearchResult,
@@ -57,13 +58,13 @@ interface VectorStoreNodeConstructorArgs {
retrieveFields?: INodeProperties[]; retrieveFields?: INodeProperties[];
updateFields?: INodeProperties[]; updateFields?: INodeProperties[];
populateVectorStore: ( populateVectorStore: (
context: IExecuteFunctions, context: ISupplyDataFunctions,
embeddings: Embeddings, embeddings: Embeddings,
documents: Array<Document<Record<string, unknown>>>, documents: Array<Document<Record<string, unknown>>>,
itemIndex: number, itemIndex: number,
) => Promise<void>; ) => Promise<void>;
getVectorStoreClient: ( getVectorStoreClient: (
context: IExecuteFunctions, context: ISupplyDataFunctions,
filter: Record<string, never> | undefined, filter: Record<string, never> | undefined,
embeddings: Embeddings, embeddings: Embeddings,
itemIndex: number, itemIndex: number,
@@ -281,7 +282,7 @@ export const createVectorStoreNode = (args: VectorStoreNodeConstructorArgs) =>
}); });
resultData.push(...serializedDocs); resultData.push(...serializedDocs);
void logAiEvent(this, 'ai-vector-store-searched', { query: prompt }); logAiEvent(this, 'ai-vector-store-searched', { query: prompt });
} }
return [resultData]; return [resultData];
@@ -311,7 +312,7 @@ export const createVectorStoreNode = (args: VectorStoreNodeConstructorArgs) =>
try { try {
await args.populateVectorStore(this, embeddings, processedDocuments, itemIndex); await args.populateVectorStore(this, embeddings, processedDocuments, itemIndex);
void logAiEvent(this, 'ai-vector-store-populated'); logAiEvent(this, 'ai-vector-store-populated');
} catch (error) { } catch (error) {
throw error; throw error;
} }
@@ -365,7 +366,7 @@ export const createVectorStoreNode = (args: VectorStoreNodeConstructorArgs) =>
ids: [documentId], ids: [documentId],
}); });
void logAiEvent(this, 'ai-vector-store-updated'); logAiEvent(this, 'ai-vector-store-updated');
} catch (error) { } catch (error) {
throw error; throw error;
} }
@@ -380,7 +381,7 @@ export const createVectorStoreNode = (args: VectorStoreNodeConstructorArgs) =>
); );
} }
async supplyData(this: IExecuteFunctions, itemIndex: number): Promise<SupplyData> { async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const mode = this.getNodeParameter('mode', 0) as 'load' | 'insert' | 'retrieve'; const mode = this.getNodeParameter('mode', 0) as 'load' | 'insert' | 'retrieve';
const filter = getMetadataFiltersValues(this, itemIndex); const filter = getMetadataFiltersValues(this, itemIndex);
const embeddings = (await this.getInputConnectionData( const embeddings = (await this.getInputConnectionData(

View File

@@ -1,6 +1,11 @@
import { pipeline } from 'stream/promises'; import { pipeline } from 'stream/promises';
import { createWriteStream } from 'fs'; import { createWriteStream } from 'fs';
import type { IBinaryData, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; import type {
IBinaryData,
IExecuteFunctions,
INodeExecutionData,
ISupplyDataFunctions,
} from 'n8n-workflow';
import { NodeOperationError, BINARY_ENCODING } from 'n8n-workflow'; import { NodeOperationError, BINARY_ENCODING } from 'n8n-workflow';
import type { TextSplitter } from '@langchain/textsplitters'; import type { TextSplitter } from '@langchain/textsplitters';
@@ -26,25 +31,12 @@ const SUPPORTED_MIME_TYPES = {
}; };
export class N8nBinaryLoader { export class N8nBinaryLoader {
private context: IExecuteFunctions;
private optionsPrefix: string;
private binaryDataKey: string;
private textSplitter?: TextSplitter;
constructor( constructor(
context: IExecuteFunctions, private context: IExecuteFunctions | ISupplyDataFunctions,
optionsPrefix = '', private optionsPrefix = '',
binaryDataKey = '', private binaryDataKey = '',
textSplitter?: TextSplitter, private textSplitter?: TextSplitter,
) { ) {}
this.context = context;
this.textSplitter = textSplitter;
this.optionsPrefix = optionsPrefix;
this.binaryDataKey = binaryDataKey;
}
async processAll(items?: INodeExecutionData[]): Promise<Document[]> { async processAll(items?: INodeExecutionData[]): Promise<Document[]> {
const docs: Document[] = []; const docs: Document[] = [];

View File

@@ -1,4 +1,9 @@
import { type IExecuteFunctions, type INodeExecutionData, NodeOperationError } from 'n8n-workflow'; import {
type IExecuteFunctions,
type INodeExecutionData,
type ISupplyDataFunctions,
NodeOperationError,
} from 'n8n-workflow';
import type { TextSplitter } from '@langchain/textsplitters'; import type { TextSplitter } from '@langchain/textsplitters';
import type { Document } from '@langchain/core/documents'; import type { Document } from '@langchain/core/documents';
@@ -7,17 +12,11 @@ import { TextLoader } from 'langchain/document_loaders/fs/text';
import { getMetadataFiltersValues } from './helpers'; import { getMetadataFiltersValues } from './helpers';
export class N8nJsonLoader { export class N8nJsonLoader {
private context: IExecuteFunctions; constructor(
private context: IExecuteFunctions | ISupplyDataFunctions,
private optionsPrefix: string; private optionsPrefix = '',
private textSplitter?: TextSplitter,
private textSplitter?: TextSplitter; ) {}
constructor(context: IExecuteFunctions, optionsPrefix = '', textSplitter?: TextSplitter) {
this.context = context;
this.textSplitter = textSplitter;
this.optionsPrefix = optionsPrefix;
}
async processAll(items?: INodeExecutionData[]): Promise<Document[]> { async processAll(items?: INodeExecutionData[]): Promise<Document[]> {
const docs: Document[] = []; const docs: Document[] = [];

View File

@@ -1,6 +1,6 @@
import type { DynamicStructuredToolInput } from '@langchain/core/tools'; import type { DynamicStructuredToolInput } from '@langchain/core/tools';
import { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools'; import { DynamicStructuredTool, DynamicTool } from '@langchain/core/tools';
import type { IExecuteFunctions, IDataObject } from 'n8n-workflow'; import type { ISupplyDataFunctions, IDataObject } from 'n8n-workflow';
import { NodeConnectionType, jsonParse, NodeOperationError } from 'n8n-workflow'; import { NodeConnectionType, jsonParse, NodeOperationError } from 'n8n-workflow';
import { StructuredOutputParser } from 'langchain/output_parsers'; import { StructuredOutputParser } from 'langchain/output_parsers';
import type { ZodTypeAny } from 'zod'; import type { ZodTypeAny } from 'zod';
@@ -45,12 +45,11 @@ ALL parameters marked as required must be provided`;
}; };
export class N8nTool extends DynamicStructuredTool { export class N8nTool extends DynamicStructuredTool {
private context: IExecuteFunctions; constructor(
private context: ISupplyDataFunctions,
constructor(context: IExecuteFunctions, fields: DynamicStructuredToolInput) { fields: DynamicStructuredToolInput,
) {
super(fields); super(fields);
this.context = context;
} }
asDynamicTool(): DynamicTool { asDynamicTool(): DynamicTool {

View File

@@ -5,7 +5,13 @@ import type { BaseMessage } from '@langchain/core/messages';
import type { Tool } from '@langchain/core/tools'; import type { Tool } from '@langchain/core/tools';
import type { BaseChatMemory } from 'langchain/memory'; import type { BaseChatMemory } from 'langchain/memory';
import { NodeConnectionType, NodeOperationError, jsonStringify } from 'n8n-workflow'; import { NodeConnectionType, NodeOperationError, jsonStringify } from 'n8n-workflow';
import type { AiEvent, IDataObject, IExecuteFunctions, IWebhookFunctions } from 'n8n-workflow'; import type {
AiEvent,
IDataObject,
IExecuteFunctions,
ISupplyDataFunctions,
IWebhookFunctions,
} from 'n8n-workflow';
import { N8nTool } from './N8nTool'; import { N8nTool } from './N8nTool';
@@ -20,7 +26,7 @@ function hasMethods<T>(obj: unknown, ...methodNames: Array<string | symbol>): ob
} }
export function getMetadataFiltersValues( export function getMetadataFiltersValues(
ctx: IExecuteFunctions, ctx: IExecuteFunctions | ISupplyDataFunctions,
itemIndex: number, itemIndex: number,
): Record<string, never> | undefined { ): Record<string, never> | undefined {
const options = ctx.getNodeParameter('options', itemIndex, {}); const options = ctx.getNodeParameter('options', itemIndex, {});
@@ -93,7 +99,7 @@ export function getPromptInputByType(options: {
} }
export function getSessionId( export function getSessionId(
ctx: IExecuteFunctions | IWebhookFunctions, ctx: ISupplyDataFunctions | IWebhookFunctions,
itemIndex: number, itemIndex: number,
selectorKey = 'sessionIdType', selectorKey = 'sessionIdType',
autoSelect = 'fromInput', autoSelect = 'fromInput',
@@ -133,13 +139,13 @@ export function getSessionId(
return sessionId; return sessionId;
} }
export async function logAiEvent( export function logAiEvent(
executeFunctions: IExecuteFunctions, executeFunctions: IExecuteFunctions | ISupplyDataFunctions,
event: AiEvent, event: AiEvent,
data?: IDataObject, data?: IDataObject,
) { ) {
try { try {
await executeFunctions.logAiEvent(event, data ? jsonStringify(data) : undefined); executeFunctions.logAiEvent(event, data ? jsonStringify(data) : undefined);
} catch (error) { } catch (error) {
executeFunctions.logger.debug(`Error logging AI event: ${event}`); executeFunctions.logger.debug(`Error logging AI event: ${event}`);
} }

View File

@@ -10,7 +10,7 @@ import type { Tool } from '@langchain/core/tools';
import { VectorStore } from '@langchain/core/vectorstores'; import { VectorStore } from '@langchain/core/vectorstores';
import { TextSplitter } from '@langchain/textsplitters'; import { TextSplitter } from '@langchain/textsplitters';
import type { BaseDocumentLoader } from 'langchain/dist/document_loaders/base'; import type { BaseDocumentLoader } from 'langchain/dist/document_loaders/base';
import type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; import type { IExecuteFunctions, INodeExecutionData, ISupplyDataFunctions } from 'n8n-workflow';
import { NodeOperationError, NodeConnectionType } from 'n8n-workflow'; import { NodeOperationError, NodeConnectionType } from 'n8n-workflow';
import { logAiEvent, isToolsInstance, isBaseChatMemory, isBaseChatMessageHistory } from './helpers'; import { logAiEvent, isToolsInstance, isBaseChatMemory, isBaseChatMessageHistory } from './helpers';
@@ -27,7 +27,7 @@ const errorsMap: { [key: string]: { message: string; description: string } } = {
export async function callMethodAsync<T>( export async function callMethodAsync<T>(
this: T, this: T,
parameters: { parameters: {
executeFunctions: IExecuteFunctions; executeFunctions: IExecuteFunctions | ISupplyDataFunctions;
connectionType: NodeConnectionType; connectionType: NodeConnectionType;
currentNodeRunIndex: number; currentNodeRunIndex: number;
method: (...args: any[]) => Promise<unknown>; method: (...args: any[]) => Promise<unknown>;
@@ -113,7 +113,7 @@ export function logWrapper(
| VectorStore | VectorStore
| N8nBinaryLoader | N8nBinaryLoader
| N8nJsonLoader, | N8nJsonLoader,
executeFunctions: IExecuteFunctions, executeFunctions: IExecuteFunctions | ISupplyDataFunctions,
) { ) {
return new Proxy(originalInstance, { return new Proxy(originalInstance, {
get: (target, prop) => { get: (target, prop) => {
@@ -190,7 +190,7 @@ export function logWrapper(
const payload = { action: 'getMessages', response }; const payload = { action: 'getMessages', response };
executeFunctions.addOutputData(connectionType, index, [[{ json: payload }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: payload }]]);
void logAiEvent(executeFunctions, 'ai-messages-retrieved-from-memory', { response }); logAiEvent(executeFunctions, 'ai-messages-retrieved-from-memory', { response });
return response; return response;
}; };
} else if (prop === 'addMessage' && 'addMessage' in target) { } else if (prop === 'addMessage' && 'addMessage' in target) {
@@ -207,7 +207,7 @@ export function logWrapper(
arguments: [message], arguments: [message],
}); });
void logAiEvent(executeFunctions, 'ai-message-added-to-memory', { message }); logAiEvent(executeFunctions, 'ai-message-added-to-memory', { message });
executeFunctions.addOutputData(connectionType, index, [[{ json: payload }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: payload }]]);
}; };
} }
@@ -233,7 +233,7 @@ export function logWrapper(
arguments: [query, config], arguments: [query, config],
})) as Array<Document<Record<string, any>>>; })) as Array<Document<Record<string, any>>>;
void logAiEvent(executeFunctions, 'ai-documents-retrieved', { query }); logAiEvent(executeFunctions, 'ai-documents-retrieved', { query });
executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]);
return response; return response;
}; };
@@ -258,7 +258,7 @@ export function logWrapper(
arguments: [documents], arguments: [documents],
})) as number[][]; })) as number[][];
void logAiEvent(executeFunctions, 'ai-document-embedded'); logAiEvent(executeFunctions, 'ai-document-embedded');
executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]);
return response; return response;
}; };
@@ -278,7 +278,7 @@ export function logWrapper(
method: target[prop], method: target[prop],
arguments: [query], arguments: [query],
})) as number[]; })) as number[];
void logAiEvent(executeFunctions, 'ai-query-embedded'); logAiEvent(executeFunctions, 'ai-query-embedded');
executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]);
return response; return response;
}; };
@@ -323,7 +323,7 @@ export function logWrapper(
arguments: [item, itemIndex], arguments: [item, itemIndex],
})) as number[]; })) as number[];
void logAiEvent(executeFunctions, 'ai-document-processed'); logAiEvent(executeFunctions, 'ai-document-processed');
executeFunctions.addOutputData(connectionType, index, [ executeFunctions.addOutputData(connectionType, index, [
[{ json: { response }, pairedItem: { item: itemIndex } }], [{ json: { response }, pairedItem: { item: itemIndex } }],
]); ]);
@@ -349,7 +349,7 @@ export function logWrapper(
arguments: [text], arguments: [text],
})) as string[]; })) as string[];
void logAiEvent(executeFunctions, 'ai-text-split'); logAiEvent(executeFunctions, 'ai-text-split');
executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]);
return response; return response;
}; };
@@ -373,7 +373,7 @@ export function logWrapper(
arguments: [query], arguments: [query],
})) as string; })) as string;
void logAiEvent(executeFunctions, 'ai-tool-called', { query, response }); logAiEvent(executeFunctions, 'ai-tool-called', { query, response });
executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]);
return response; return response;
}; };
@@ -403,7 +403,7 @@ export function logWrapper(
arguments: [query, k, filter, _callbacks], arguments: [query, k, filter, _callbacks],
})) as Array<Document<Record<string, any>>>; })) as Array<Document<Record<string, any>>>;
void logAiEvent(executeFunctions, 'ai-vector-store-searched', { query }); logAiEvent(executeFunctions, 'ai-vector-store-searched', { query });
executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]); executeFunctions.addOutputData(connectionType, index, [[{ json: { response } }]]);
return response; return response;

View File

@@ -2,7 +2,7 @@ import type { Callbacks } from '@langchain/core/callbacks/manager';
import type { BaseLanguageModel } from '@langchain/core/language_models/base'; import type { BaseLanguageModel } from '@langchain/core/language_models/base';
import type { AIMessage } from '@langchain/core/messages'; import type { AIMessage } from '@langchain/core/messages';
import { BaseOutputParser } from '@langchain/core/output_parsers'; import { BaseOutputParser } from '@langchain/core/output_parsers';
import type { IExecuteFunctions } from 'n8n-workflow'; import type { ISupplyDataFunctions } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow'; import { NodeConnectionType } from 'n8n-workflow';
import type { N8nStructuredOutputParser } from './N8nStructuredOutputParser'; import type { N8nStructuredOutputParser } from './N8nStructuredOutputParser';
@@ -10,23 +10,14 @@ import { NAIVE_FIX_PROMPT } from './prompt';
import { logAiEvent } from '../helpers'; import { logAiEvent } from '../helpers';
export class N8nOutputFixingParser extends BaseOutputParser { export class N8nOutputFixingParser extends BaseOutputParser {
private context: IExecuteFunctions;
private model: BaseLanguageModel;
private outputParser: N8nStructuredOutputParser;
lc_namespace = ['langchain', 'output_parsers', 'fix']; lc_namespace = ['langchain', 'output_parsers', 'fix'];
constructor( constructor(
context: IExecuteFunctions, private context: ISupplyDataFunctions,
model: BaseLanguageModel, private model: BaseLanguageModel,
outputParser: N8nStructuredOutputParser, private outputParser: N8nStructuredOutputParser,
) { ) {
super(); super();
this.context = context;
this.model = model;
this.outputParser = outputParser;
} }
getRetryChain() { getRetryChain() {
@@ -48,7 +39,7 @@ export class N8nOutputFixingParser extends BaseOutputParser {
try { try {
// First attempt to parse the completion // First attempt to parse the completion
const response = await this.outputParser.parse(completion, callbacks, (e) => e); const response = await this.outputParser.parse(completion, callbacks, (e) => e);
void logAiEvent(this.context, 'ai-output-parsed', { text: completion, response }); logAiEvent(this.context, 'ai-output-parsed', { text: completion, response });
this.context.addOutputData(NodeConnectionType.AiOutputParser, index, [ this.context.addOutputData(NodeConnectionType.AiOutputParser, index, [
[{ json: { action: 'parse', response } }], [{ json: { action: 'parse', response } }],

View File

@@ -1,7 +1,7 @@
import type { Callbacks } from '@langchain/core/callbacks/manager'; import type { Callbacks } from '@langchain/core/callbacks/manager';
import { StructuredOutputParser } from 'langchain/output_parsers'; import { StructuredOutputParser } from 'langchain/output_parsers';
import get from 'lodash/get'; import get from 'lodash/get';
import type { IExecuteFunctions } from 'n8n-workflow'; import type { ISupplyDataFunctions } from 'n8n-workflow';
import { NodeConnectionType, NodeOperationError } from 'n8n-workflow'; import { NodeConnectionType, NodeOperationError } from 'n8n-workflow';
import { z } from 'zod'; import { z } from 'zod';
@@ -14,11 +14,11 @@ const STRUCTURED_OUTPUT_ARRAY_KEY = '__structured__output__array';
export class N8nStructuredOutputParser extends StructuredOutputParser< export class N8nStructuredOutputParser extends StructuredOutputParser<
z.ZodType<object, z.ZodTypeDef, object> z.ZodType<object, z.ZodTypeDef, object>
> { > {
context: IExecuteFunctions; constructor(
private context: ISupplyDataFunctions,
constructor(context: IExecuteFunctions, zodSchema: z.ZodSchema<object>) { zodSchema: z.ZodSchema<object>,
) {
super(zodSchema); super(zodSchema);
this.context = context;
} }
lc_namespace = ['langchain', 'output_parsers', 'structured']; lc_namespace = ['langchain', 'output_parsers', 'structured'];
@@ -39,7 +39,7 @@ export class N8nStructuredOutputParser extends StructuredOutputParser<
get(parsed, STRUCTURED_OUTPUT_KEY) ?? get(parsed, STRUCTURED_OUTPUT_KEY) ??
parsed) as Record<string, unknown>; parsed) as Record<string, unknown>;
void logAiEvent(this.context, 'ai-output-parsed', { text, response: result }); logAiEvent(this.context, 'ai-output-parsed', { text, response: result });
this.context.addOutputData(NodeConnectionType.AiOutputParser, index, [ this.context.addOutputData(NodeConnectionType.AiOutputParser, index, [
[{ json: { action: 'parse', response: result } }], [{ json: { action: 'parse', response: result } }],
@@ -56,7 +56,7 @@ export class N8nStructuredOutputParser extends StructuredOutputParser<
}, },
); );
void logAiEvent(this.context, 'ai-output-parsed', { logAiEvent(this.context, 'ai-output-parsed', {
text, text,
response: e.message ?? e, response: e.message ?? e,
}); });
@@ -73,7 +73,7 @@ export class N8nStructuredOutputParser extends StructuredOutputParser<
static async fromZodJsonSchema( static async fromZodJsonSchema(
zodSchema: z.ZodSchema<object>, zodSchema: z.ZodSchema<object>,
nodeVersion: number, nodeVersion: number,
context: IExecuteFunctions, context: ISupplyDataFunctions,
): Promise<N8nStructuredOutputParser> { ): Promise<N8nStructuredOutputParser> {
let returnSchema: z.ZodType<object, z.ZodTypeDef, object>; let returnSchema: z.ZodType<object, z.ZodTypeDef, object>;
if (nodeVersion === 1) { if (nodeVersion === 1) {

View File

@@ -110,6 +110,7 @@ import type {
DeduplicationItemTypes, DeduplicationItemTypes,
ICheckProcessedContextData, ICheckProcessedContextData,
AiEvent, AiEvent,
ISupplyDataFunctions,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { import {
NodeConnectionType, NodeConnectionType,
@@ -2803,12 +2804,14 @@ async function getInputConnectionData(
runExecutionData: IRunExecutionData, runExecutionData: IRunExecutionData,
runIndex: number, runIndex: number,
connectionInputData: INodeExecutionData[], connectionInputData: INodeExecutionData[],
inputData: ITaskDataConnections,
additionalData: IWorkflowExecuteAdditionalData, additionalData: IWorkflowExecuteAdditionalData,
executeData: IExecuteData | undefined, executeData: IExecuteData,
mode: WorkflowExecuteMode, mode: WorkflowExecuteMode,
closeFunctions: CloseFunction[], closeFunctions: CloseFunction[],
inputName: NodeConnectionType, inputName: NodeConnectionType,
itemIndex: number, itemIndex: number,
abortSignal?: AbortSignal,
): Promise<unknown> { ): Promise<unknown> {
const node = this.getNode(); const node = this.getNode();
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion); const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
@@ -2856,74 +2859,20 @@ async function getInputConnectionData(
connectedNode.typeVersion, connectedNode.typeVersion,
); );
// TODO: create a new context object here based on the type of `connectedNode`, and avoid using `Object.assign` on context objects // eslint-disable-next-line @typescript-eslint/no-use-before-define
// https://linear.app/n8n/issue/CAT-269 const context = getSupplyDataFunctions(
const context = Object.assign({}, this); workflow,
runExecutionData,
context.getNodeParameter = ( runIndex,
parameterName: string, connectionInputData,
itemIndex: number, inputData,
fallbackValue?: any, connectedNode,
options?: IGetNodeParameterOptions, additionalData,
) => { executeData,
return getNodeParameter( mode,
workflow, closeFunctions,
runExecutionData, abortSignal,
runIndex, );
connectionInputData,
connectedNode,
parameterName,
itemIndex,
mode,
getAdditionalKeys(additionalData, mode, runExecutionData),
executeData,
fallbackValue,
{ ...(options || {}), contextNode: node },
) as any;
};
// TODO: Check what else should be overwritten
context.getNode = () => {
return deepCopy(connectedNode);
};
context.getCredentials = async (key: string) => {
try {
return await getCredentials(
workflow,
connectedNode,
key,
additionalData,
mode,
executeData,
runExecutionData,
runIndex,
connectionInputData,
itemIndex,
);
} catch (error) {
// Display the error on the node which is causing it
let currentNodeRunIndex = 0;
if (runExecutionData.resultData.runData.hasOwnProperty(node.name)) {
currentNodeRunIndex = runExecutionData.resultData.runData[node.name].length;
}
await addExecutionDataFunctions(
'input',
connectedNode.name,
error,
runExecutionData,
inputName,
additionalData,
node.name,
runIndex,
currentNodeRunIndex,
);
throw error;
}
};
if (!nodeType.supplyData) { if (!nodeType.supplyData) {
if (nodeType.description.outputs.includes(NodeConnectionType.AiTool)) { if (nodeType.description.outputs.includes(NodeConnectionType.AiTool)) {
@@ -3767,9 +3716,7 @@ export function getExecuteFunctions(
runExecutionData, runExecutionData,
runIndex, runIndex,
itemIndex, itemIndex,
// TODO: revert this back to `node.name` when we stop using `IExecuteFunctions` as the context object in AI nodes. node.name,
// https://linear.app/n8n/issue/CAT-269
this.getNode().name,
connectionInputData, connectionInputData,
mode, mode,
getAdditionalKeys(additionalData, mode, runExecutionData), getAdditionalKeys(additionalData, mode, runExecutionData),
@@ -3812,12 +3759,14 @@ export function getExecuteFunctions(
runExecutionData, runExecutionData,
runIndex, runIndex,
connectionInputData, connectionInputData,
inputData,
additionalData, additionalData,
executeData, executeData,
mode, mode,
closeFunctions, closeFunctions,
inputName, inputName,
itemIndex, itemIndex,
abortSignal,
); );
}, },
@@ -4031,7 +3980,7 @@ export function getExecuteFunctions(
constructExecutionMetaData, constructExecutionMetaData,
}, },
nodeHelpers: getNodeHelperFunctions(additionalData, workflow.id), nodeHelpers: getNodeHelperFunctions(additionalData, workflow.id),
logAiEvent: async (eventName: AiEvent, msg: string) => { logAiEvent: (eventName: AiEvent, msg: string) => {
return additionalData.logAiEvent(eventName, { return additionalData.logAiEvent(eventName, {
executionId: additionalData.executionId ?? 'unsaved-execution', executionId: additionalData.executionId ?? 'unsaved-execution',
nodeName: node.name, nodeName: node.name,
@@ -4059,6 +4008,270 @@ export function getExecuteFunctions(
})(workflow, runExecutionData, connectionInputData, inputData, node) as IExecuteFunctions; })(workflow, runExecutionData, connectionInputData, inputData, node) as IExecuteFunctions;
} }
export function getSupplyDataFunctions(
workflow: Workflow,
runExecutionData: IRunExecutionData,
runIndex: number,
connectionInputData: INodeExecutionData[],
inputData: ITaskDataConnections,
node: INode,
additionalData: IWorkflowExecuteAdditionalData,
executeData: IExecuteData,
mode: WorkflowExecuteMode,
closeFunctions: CloseFunction[],
abortSignal?: AbortSignal,
): ISupplyDataFunctions {
return {
...getCommonWorkflowFunctions(workflow, node, additionalData),
...executionCancellationFunctions(abortSignal),
getMode: () => mode,
getCredentials: async (type, itemIndex) =>
await getCredentials(
workflow,
node,
type,
additionalData,
mode,
executeData,
runExecutionData,
runIndex,
connectionInputData,
itemIndex,
),
continueOnFail: () => continueOnFail(node),
evaluateExpression: (expression: string, itemIndex: number) =>
workflow.expression.resolveSimpleParameterValue(
`=${expression}`,
{},
runExecutionData,
runIndex,
itemIndex,
node.name,
connectionInputData,
mode,
getAdditionalKeys(additionalData, mode, runExecutionData),
executeData,
),
executeWorkflow: async (
workflowInfo: IExecuteWorkflowInfo,
inputData?: INodeExecutionData[],
parentCallbackManager?: CallbackManager,
) =>
await additionalData
.executeWorkflow(workflowInfo, additionalData, {
parentWorkflowId: workflow.id?.toString(),
inputData,
parentWorkflowSettings: workflow.settings,
node,
parentCallbackManager,
})
.then(
async (result) =>
await Container.get(BinaryDataService).duplicateBinaryData(
workflow.id,
additionalData.executionId!,
result,
),
),
getNodeOutputs() {
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
return NodeHelpers.getNodeOutputs(workflow, node, nodeType.description).map((output) => {
if (typeof output === 'string') {
return {
type: output,
};
}
return output;
});
},
async getInputConnectionData(
inputName: NodeConnectionType,
itemIndex: number,
): Promise<unknown> {
return await getInputConnectionData.call(
this,
workflow,
runExecutionData,
runIndex,
connectionInputData,
inputData,
additionalData,
executeData,
mode,
closeFunctions,
inputName,
itemIndex,
abortSignal,
);
},
getInputData: (inputIndex = 0, inputName = 'main') => {
if (!inputData.hasOwnProperty(inputName)) {
// Return empty array because else it would throw error when nothing is connected to input
return [];
}
// TODO: Check if nodeType has input with that index defined
if (inputData[inputName].length < inputIndex) {
throw new ApplicationError('Could not get input with given index', {
extra: { inputIndex, inputName },
});
}
if (inputData[inputName][inputIndex] === null) {
throw new ApplicationError('Value of input was not set', {
extra: { inputIndex, inputName },
});
}
return inputData[inputName][inputIndex];
},
getNodeParameter: ((
parameterName: string,
itemIndex: number,
fallbackValue?: any,
options?: IGetNodeParameterOptions,
) =>
getNodeParameter(
workflow,
runExecutionData,
runIndex,
connectionInputData,
node,
parameterName,
itemIndex,
mode,
getAdditionalKeys(additionalData, mode, runExecutionData),
executeData,
fallbackValue,
options,
)) as ISupplyDataFunctions['getNodeParameter'],
getWorkflowDataProxy: (itemIndex: number) =>
new WorkflowDataProxy(
workflow,
runExecutionData,
runIndex,
itemIndex,
node.name,
connectionInputData,
{},
mode,
getAdditionalKeys(additionalData, mode, runExecutionData),
executeData,
).getDataProxy(),
sendMessageToUI(...args: any[]): void {
if (mode !== 'manual') {
return;
}
try {
if (additionalData.sendDataToUI) {
args = args.map((arg) => {
// prevent invalid dates from being logged as null
if (arg.isLuxonDateTime && arg.invalidReason) return { ...arg };
// log valid dates in human readable format, as in browser
if (arg.isLuxonDateTime) return new Date(arg.ts).toString();
if (arg instanceof Date) return arg.toString();
return arg;
});
additionalData.sendDataToUI('sendConsoleMessage', {
source: `[Node: "${node.name}"]`,
messages: args,
});
}
} catch (error) {
Logger.warn(`There was a problem sending message to UI: ${error.message}`);
}
},
logAiEvent: (eventName: AiEvent, msg: string) =>
additionalData.logAiEvent(eventName, {
executionId: additionalData.executionId ?? 'unsaved-execution',
nodeName: node.name,
workflowName: workflow.name ?? 'Unnamed workflow',
nodeType: node.type,
workflowId: workflow.id ?? 'unsaved-workflow',
msg,
}),
addInputData(
connectionType: NodeConnectionType,
data: INodeExecutionData[][],
): { index: number } {
const nodeName = this.getNode().name;
let currentNodeRunIndex = 0;
if (runExecutionData.resultData.runData.hasOwnProperty(nodeName)) {
currentNodeRunIndex = runExecutionData.resultData.runData[nodeName].length;
}
addExecutionDataFunctions(
'input',
this.getNode().name,
data,
runExecutionData,
connectionType,
additionalData,
node.name,
runIndex,
currentNodeRunIndex,
).catch((error) => {
Logger.warn(
`There was a problem logging input data of node "${this.getNode().name}": ${
error.message
}`,
);
});
return { index: currentNodeRunIndex };
},
addOutputData(
connectionType: NodeConnectionType,
currentNodeRunIndex: number,
data: INodeExecutionData[][],
): void {
addExecutionDataFunctions(
'output',
this.getNode().name,
data,
runExecutionData,
connectionType,
additionalData,
node.name,
runIndex,
currentNodeRunIndex,
).catch((error) => {
Logger.warn(
`There was a problem logging output data of node "${this.getNode().name}": ${
error.message
}`,
);
});
},
helpers: {
createDeferredPromise,
copyInputItems,
...getRequestHelperFunctions(
workflow,
node,
additionalData,
runExecutionData,
connectionInputData,
),
...getSSHTunnelFunctions(),
...getFileSystemHelperFunctions(node),
...getBinaryHelperFunctions(additionalData, workflow.id),
...getCheckProcessedHelperFunctions(workflow, node),
assertBinaryData: (itemIndex, propertyName) =>
assertBinaryData(inputData, node, itemIndex, propertyName, 0),
getBinaryDataBuffer: async (itemIndex, propertyName) =>
await getBinaryDataBuffer(inputData, itemIndex, propertyName, 0),
returnJsonArray,
normalizeItems,
constructExecutionMetaData,
},
};
}
/** /**
* Returns the execute functions regular nodes have access to when single-function is defined. * Returns the execute functions regular nodes have access to when single-function is defined.
*/ */
@@ -4201,7 +4414,7 @@ export function getExecuteSingleFunctions(
getBinaryDataBuffer: async (propertyName, inputIndex = 0) => getBinaryDataBuffer: async (propertyName, inputIndex = 0) =>
await getBinaryDataBuffer(inputData, itemIndex, propertyName, inputIndex), await getBinaryDataBuffer(inputData, itemIndex, propertyName, inputIndex),
}, },
logAiEvent: async (eventName: AiEvent, msg: string) => { logAiEvent: (eventName: AiEvent, msg: string) => {
return additionalData.logAiEvent(eventName, { return additionalData.logAiEvent(eventName, {
executionId: additionalData.executionId ?? 'unsaved-execution', executionId: additionalData.executionId ?? 'unsaved-execution',
nodeName: node.name, nodeName: node.name,
@@ -4431,6 +4644,7 @@ export function getExecuteWebhookFunctions(
runExecutionData, runExecutionData,
runIndex, runIndex,
connectionInputData, connectionInputData,
{} as ITaskDataConnections,
additionalData, additionalData,
executeData, executeData,
mode, mode,

View File

@@ -1,5 +1,10 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import type { IExecuteFunctions, INodeExecutionData, IWorkflowDataProxyData } from 'n8n-workflow'; import type {
IExecuteFunctions,
INodeExecutionData,
ISupplyDataFunctions,
IWorkflowDataProxyData,
} from 'n8n-workflow';
import { isObject } from './utils'; import { isObject } from './utils';
import { ValidationError } from './ValidationError'; import { ValidationError } from './ValidationError';
@@ -19,7 +24,10 @@ export interface SandboxContext extends IWorkflowDataProxyData {
export const REQUIRED_N8N_ITEM_KEYS = new Set(['json', 'binary', 'pairedItem', 'error']); export const REQUIRED_N8N_ITEM_KEYS = new Set(['json', 'binary', 'pairedItem', 'error']);
export function getSandboxContext(this: IExecuteFunctions, index: number): SandboxContext { export function getSandboxContext(
this: IExecuteFunctions | ISupplyDataFunctions,
index: number,
): SandboxContext {
const helpers = { const helpers = {
...this.helpers, ...this.helpers,
httpRequestWithAuthentication: this.helpers.httpRequestWithAuthentication.bind(this), httpRequestWithAuthentication: this.helpers.httpRequestWithAuthentication.bind(this),

View File

@@ -4,6 +4,7 @@ import type {
IExecuteFunctions, IExecuteFunctions,
INode, INode,
INodeExecutionData, INodeExecutionData,
ISupplyDataFunctions,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { import {
ApplicationError, ApplicationError,
@@ -51,7 +52,7 @@ const configureFieldHelper = (dotNotation?: boolean) => {
}; };
export function composeReturnItem( export function composeReturnItem(
this: IExecuteFunctions, this: IExecuteFunctions | ISupplyDataFunctions,
itemIndex: number, itemIndex: number,
inputItem: INodeExecutionData, inputItem: INodeExecutionData,
newFields: IDataObject, newFields: IDataObject,
@@ -220,7 +221,11 @@ export const validateEntry = (
}; };
}; };
export function resolveRawData(this: IExecuteFunctions, rawData: string, i: number) { export function resolveRawData(
this: IExecuteFunctions | ISupplyDataFunctions,
rawData: string,
i: number,
) {
const resolvables = getResolvables(rawData); const resolvables = getResolvables(rawData);
let returnData: string = rawData; let returnData: string = rawData;

View File

@@ -6,6 +6,7 @@ import type {
INode, INode,
INodeExecutionData, INodeExecutionData,
INodeProperties, INodeProperties,
ISupplyDataFunctions,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { NodeOperationError } from 'n8n-workflow'; import { NodeOperationError } from 'n8n-workflow';
@@ -185,7 +186,7 @@ const displayOptions = {
export const description = updateDisplayOptions(displayOptions, properties); export const description = updateDisplayOptions(displayOptions, properties);
export async function execute( export async function execute(
this: IExecuteFunctions, this: IExecuteFunctions | ISupplyDataFunctions,
item: INodeExecutionData, item: INodeExecutionData,
i: number, i: number,
options: SetNodeOptions, options: SetNodeOptions,

View File

@@ -35,6 +35,7 @@ export type IAllExecuteFunctions =
| IExecuteFunctions | IExecuteFunctions
| IExecutePaginationFunctions | IExecutePaginationFunctions
| IExecuteSingleFunctions | IExecuteSingleFunctions
| ISupplyDataFunctions
| IHookFunctions | IHookFunctions
| ILoadOptionsFunctions | ILoadOptionsFunctions
| IPollFunctions | IPollFunctions
@@ -943,7 +944,7 @@ type BaseExecutionFunctions = FunctionsBaseWithRequiredKeys<'getMode'> & {
getInputSourceData(inputIndex?: number, inputName?: string): ISourceData; getInputSourceData(inputIndex?: number, inputName?: string): ISourceData;
getExecutionCancelSignal(): AbortSignal | undefined; getExecutionCancelSignal(): AbortSignal | undefined;
onExecutionCancellation(handler: () => unknown): void; onExecutionCancellation(handler: () => unknown): void;
logAiEvent(eventName: AiEvent, msg?: string | undefined): Promise<void>; logAiEvent(eventName: AiEvent, msg?: string | undefined): void;
}; };
// TODO: Create later own type only for Config-Nodes // TODO: Create later own type only for Config-Nodes
@@ -1022,6 +1023,27 @@ export interface IExecuteSingleFunctions extends BaseExecutionFunctions {
}; };
} }
export type ISupplyDataFunctions = ExecuteFunctions.GetNodeParameterFn &
FunctionsBaseWithRequiredKeys<'getMode'> &
Pick<
IExecuteFunctions,
| 'addInputData'
| 'addOutputData'
| 'getInputConnectionData'
| 'getInputData'
| 'getNodeOutputs'
| 'executeWorkflow'
| 'sendMessageToUI'
| 'helpers'
> & {
continueOnFail(): boolean;
evaluateExpression(expression: string, itemIndex: number): NodeParameterValueType;
getWorkflowDataProxy(itemIndex: number): IWorkflowDataProxyData;
getExecutionCancelSignal(): AbortSignal | undefined;
onExecutionCancellation(handler: () => unknown): void;
logAiEvent(eventName: AiEvent, msg?: string | undefined): void;
};
export interface IExecutePaginationFunctions extends IExecuteSingleFunctions { export interface IExecutePaginationFunctions extends IExecuteSingleFunctions {
makeRoutingRequest( makeRoutingRequest(
this: IAllExecuteFunctions, this: IAllExecuteFunctions,
@@ -1572,7 +1594,7 @@ export class NodeExecutionOutput extends Array {
export interface INodeType { export interface INodeType {
description: INodeTypeDescription; description: INodeTypeDescription;
supplyData?(this: IAllExecuteFunctions, itemIndex: number): Promise<SupplyData>; supplyData?(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
execute?( execute?(
this: IExecuteFunctions, this: IExecuteFunctions,
): Promise<INodeExecutionData[][] | NodeExecutionWithMetadata[][] | null>; ): Promise<INodeExecutionData[][] | NodeExecutionWithMetadata[][] | null>;