@n8n/n8n-nodes-langchain 1.92.0 → 1.92.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nodes/agents/Agent/agents/ToolsAgent/description.js +0 -23
- package/dist/nodes/agents/Agent/agents/ToolsAgent/description.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/execute.js +13 -28
- package/dist/nodes/agents/Agent/agents/ToolsAgent/execute.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/ChainLlm.node.js +21 -39
- package/dist/nodes/chains/ChainLLM/ChainLlm.node.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/methods/config.js +0 -24
- package/dist/nodes/chains/ChainLLM/methods/config.js.map +1 -1
- package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js +15 -55
- package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js.map +1 -1
- package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js +11 -54
- package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js.map +1 -1
- package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js +24 -66
- package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js.map +1 -1
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js +27 -86
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js.map +1 -1
- package/dist/nodes/chains/TextClassifier/TextClassifier.node.js +47 -81
- package/dist/nodes/chains/TextClassifier/TextClassifier.node.js.map +1 -1
- package/dist/types/nodes.json +7 -7
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport {\n\tChatPromptTemplate,\n\tSystemMessagePromptTemplate,\n\tHumanMessagePromptTemplate,\n\tPromptTemplate,\n} from '@langchain/core/prompts';\nimport type { BaseRetriever } from '@langchain/core/retrievers';\nimport { createStuffDocumentsChain } from 'langchain/chains/combine_documents';\nimport { createRetrievalChain } from 'langchain/chains/retrieval';\nimport { NodeConnectionTypes, NodeOperationError, parseErrorMetadata, sleep } from 'n8n-workflow';\nimport {\n\ttype INodeProperties,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { promptTypeOptions, textFromPreviousNode } from '@utils/descriptions';\nimport { getPromptInputByType, isChatInstance } from '@utils/helpers';\nimport { getTemplateNoticeField } from '@utils/sharedFields';\nimport { getTracingConfig } from '@utils/tracing';\n\nconst SYSTEM_PROMPT_TEMPLATE = `You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question.\nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n----------------\nContext: {context}`;\n\n// Due to the refactoring in version 1.5, the variable name {question} needed to be changed to {input} in the prompt template.\nconst LEGACY_INPUT_TEMPLATE_KEY = 'question';\nconst INPUT_TEMPLATE_KEY = 'input';\n\nconst systemPromptOption: INodeProperties = {\n\tdisplayName: 'System Prompt Template',\n\tname: 'systemPromptTemplate',\n\ttype: 'string',\n\tdefault: SYSTEM_PROMPT_TEMPLATE,\n\ttypeOptions: {\n\t\trows: 6,\n\t},\n};\n\nexport class ChainRetrievalQa implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Question and Answer Chain',\n\t\tname: 'chainRetrievalQa',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5],\n\t\tdescription: 'Answer questions about retrieved documents',\n\t\tdefaults: {\n\t\t\tname: 'Question and Answer Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainretrievalqa/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [\n\t\t\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Retriever',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiRetriever,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: [\n\t\t\tgetTemplateNoticeField(1960),\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...promptTypeOptions,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...textFromPreviousNode,\n\t\t\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.4 } }] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Prompt (User Message)',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpromptType: ['define'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${LEGACY_INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Batch Processing',\n\t\t\t\t\t\tname: 'batching',\n\t\t\t\t\t\ttype: 'collection',\n\t\t\t\t\t\tdescription: 'Batch processing options for rate limiting',\n\t\t\t\t\t\tdefault: {},\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Batch Size',\n\t\t\t\t\t\t\t\tname: 'batchSize',\n\t\t\t\t\t\t\t\tdefault: 100,\n\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'How many items to process in parallel. This is useful for rate limiting.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Delay Between Batches',\n\t\t\t\t\t\t\t\tname: 'delayBetweenBatches',\n\t\t\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Delay in milliseconds between batches. This is useful for rate limiting.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Retrieval QA Chain');\n\n\t\tconst items = this.getInputData();\n\t\tconst { batchSize, delayBetweenBatches } = this.getNodeParameter('options.batching', 0, {\n\t\t\tbatchSize: 100,\n\t\t\tdelayBetweenBatches: 0,\n\t\t}) as {\n\t\t\tbatchSize: number;\n\t\t\tdelayBetweenBatches: number;\n\t\t};\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\tconst batchPromises = batch.map(async (_item, batchIndex) => {\n\t\t\t\tconst itemIndex = i + batchIndex;\n\n\t\t\t\tconst model = (await this.getInputConnectionData(\n\t\t\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t\t\t0,\n\t\t\t\t)) as BaseLanguageModel;\n\n\t\t\t\tconst retriever = (await this.getInputConnectionData(\n\t\t\t\t\tNodeConnectionTypes.AiRetriever,\n\t\t\t\t\t0,\n\t\t\t\t)) as BaseRetriever;\n\n\t\t\t\tlet query;\n\n\t\t\t\tif (this.getNode().typeVersion <= 1.2) {\n\t\t\t\t\tquery = this.getNodeParameter('query', itemIndex) as string;\n\t\t\t\t} else {\n\t\t\t\t\tquery = getPromptInputByType({\n\t\t\t\t\t\tctx: this,\n\t\t\t\t\t\ti: itemIndex,\n\t\t\t\t\t\tinputKey: 'text',\n\t\t\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (query === undefined) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘query‘ parameter is empty.');\n\t\t\t\t}\n\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\t\tsystemPromptTemplate?: string;\n\t\t\t\t};\n\n\t\t\t\tlet templateText = options.systemPromptTemplate ?? SYSTEM_PROMPT_TEMPLATE;\n\n\t\t\t\t// Replace legacy input template key for versions 1.4 and below\n\t\t\t\tif (this.getNode().typeVersion < 1.5) {\n\t\t\t\t\ttemplateText = templateText.replace(\n\t\t\t\t\t\t`{${LEGACY_INPUT_TEMPLATE_KEY}}`,\n\t\t\t\t\t\t`{${INPUT_TEMPLATE_KEY}}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Create prompt template based on model type and user configuration\n\t\t\t\tlet promptTemplate;\n\t\t\t\tif (isChatInstance(model)) {\n\t\t\t\t\t// For chat models, create a chat prompt template with system and human messages\n\t\t\t\t\tconst messages = [\n\t\t\t\t\t\tSystemMessagePromptTemplate.fromTemplate(templateText),\n\t\t\t\t\t\tHumanMessagePromptTemplate.fromTemplate('{input}'),\n\t\t\t\t\t];\n\t\t\t\t\tpromptTemplate = ChatPromptTemplate.fromMessages(messages);\n\t\t\t\t} else {\n\t\t\t\t\t// For non-chat models, create a text prompt template with Question/Answer format\n\t\t\t\t\tconst questionSuffix =\n\t\t\t\t\t\toptions.systemPromptTemplate === undefined ? '\\n\\nQuestion: {input}\\nAnswer:' : '';\n\n\t\t\t\t\tpromptTemplate = new PromptTemplate({\n\t\t\t\t\t\ttemplate: templateText + questionSuffix,\n\t\t\t\t\t\tinputVariables: ['context', 'input'],\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Create the document chain that combines the retrieved documents\n\t\t\t\tconst combineDocsChain = await createStuffDocumentsChain({\n\t\t\t\t\tllm: model,\n\t\t\t\t\tprompt: promptTemplate,\n\t\t\t\t});\n\n\t\t\t\t// Create the retrieval chain that handles the retrieval and then passes to the combine docs chain\n\t\t\t\tconst retrievalChain = await createRetrievalChain({\n\t\t\t\t\tcombineDocsChain,\n\t\t\t\t\tretriever,\n\t\t\t\t});\n\n\t\t\t\t// Execute the chain with tracing config\n\t\t\t\tconst tracingConfig = getTracingConfig(this);\n\n\t\t\t\tconst result = await retrievalChain\n\t\t\t\t\t.withConfig(tracingConfig)\n\t\t\t\t\t.invoke({ input: query }, { signal: this.getExecutionCancelSignal() });\n\n\t\t\t\treturn result;\n\t\t\t});\n\n\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\tconst error = response.reason;\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\tpairedItem: { item: index },\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst output = response.value;\n\t\t\t\tconst answer: string = output.answer;\n\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t} else {\n\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Add delay between batches if not the last batch\n\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport {\n\tChatPromptTemplate,\n\tSystemMessagePromptTemplate,\n\tHumanMessagePromptTemplate,\n\tPromptTemplate,\n} from '@langchain/core/prompts';\nimport type { BaseRetriever } from '@langchain/core/retrievers';\nimport { createStuffDocumentsChain } from 'langchain/chains/combine_documents';\nimport { createRetrievalChain } from 'langchain/chains/retrieval';\nimport { NodeConnectionTypes, NodeOperationError, parseErrorMetadata } from 'n8n-workflow';\nimport {\n\ttype INodeProperties,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport { promptTypeOptions, textFromPreviousNode } from '@utils/descriptions';\nimport { getPromptInputByType, isChatInstance } from '@utils/helpers';\nimport { getTemplateNoticeField } from '@utils/sharedFields';\nimport { getTracingConfig } from '@utils/tracing';\n\nconst SYSTEM_PROMPT_TEMPLATE = `You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question.\nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n----------------\nContext: {context}`;\n\n// Due to the refactoring in version 1.5, the variable name {question} needed to be changed to {input} in the prompt template.\nconst LEGACY_INPUT_TEMPLATE_KEY = 'question';\nconst INPUT_TEMPLATE_KEY = 'input';\n\nconst systemPromptOption: INodeProperties = {\n\tdisplayName: 'System Prompt Template',\n\tname: 'systemPromptTemplate',\n\ttype: 'string',\n\tdefault: SYSTEM_PROMPT_TEMPLATE,\n\ttypeOptions: {\n\t\trows: 6,\n\t},\n};\n\nexport class ChainRetrievalQa implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Question and Answer Chain',\n\t\tname: 'chainRetrievalQa',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5],\n\t\tdescription: 'Answer questions about retrieved documents',\n\t\tdefaults: {\n\t\t\tname: 'Question and Answer Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainretrievalqa/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\tinputs: [\n\t\t\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Retriever',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiRetriever,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: [\n\t\t\tgetTemplateNoticeField(1960),\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Query',\n\t\t\t\tname: 'query',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...promptTypeOptions,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...textFromPreviousNode,\n\t\t\t\tdisplayOptions: { show: { promptType: ['auto'], '@version': [{ _cnd: { gte: 1.4 } }] } },\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Prompt (User Message)',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpromptType: ['define'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${LEGACY_INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t...systemPromptOption,\n\t\t\t\t\t\tdescription: `Template string used for the system prompt. This should include the variable \\`{context}\\` for the provided context. For text completion models, you should also include the variable \\`{${INPUT_TEMPLATE_KEY}}\\` for the user’s query.`,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.5 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Retrieval QA Chain');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\t// Run for each item\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst model = (await this.getInputConnectionData(\n\t\t\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t\t\t0,\n\t\t\t\t)) as BaseLanguageModel;\n\n\t\t\t\tconst retriever = (await this.getInputConnectionData(\n\t\t\t\t\tNodeConnectionTypes.AiRetriever,\n\t\t\t\t\t0,\n\t\t\t\t)) as BaseRetriever;\n\n\t\t\t\tlet query;\n\n\t\t\t\tif (this.getNode().typeVersion <= 1.2) {\n\t\t\t\t\tquery = this.getNodeParameter('query', itemIndex) as string;\n\t\t\t\t} else {\n\t\t\t\t\tquery = getPromptInputByType({\n\t\t\t\t\t\tctx: this,\n\t\t\t\t\t\ti: itemIndex,\n\t\t\t\t\t\tinputKey: 'text',\n\t\t\t\t\t\tpromptTypeKey: 'promptType',\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (query === undefined) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘query‘ parameter is empty.');\n\t\t\t\t}\n\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\t\tsystemPromptTemplate?: string;\n\t\t\t\t};\n\n\t\t\t\tlet templateText = options.systemPromptTemplate ?? SYSTEM_PROMPT_TEMPLATE;\n\n\t\t\t\t// Replace legacy input template key for versions 1.4 and below\n\t\t\t\tif (this.getNode().typeVersion < 1.5) {\n\t\t\t\t\ttemplateText = templateText.replace(\n\t\t\t\t\t\t`{${LEGACY_INPUT_TEMPLATE_KEY}}`,\n\t\t\t\t\t\t`{${INPUT_TEMPLATE_KEY}}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Create prompt template based on model type and user configuration\n\t\t\t\tlet promptTemplate;\n\t\t\t\tif (isChatInstance(model)) {\n\t\t\t\t\t// For chat models, create a chat prompt template with system and human messages\n\t\t\t\t\tconst messages = [\n\t\t\t\t\t\tSystemMessagePromptTemplate.fromTemplate(templateText),\n\t\t\t\t\t\tHumanMessagePromptTemplate.fromTemplate('{input}'),\n\t\t\t\t\t];\n\t\t\t\t\tpromptTemplate = ChatPromptTemplate.fromMessages(messages);\n\t\t\t\t} else {\n\t\t\t\t\t// For non-chat models, create a text prompt template with Question/Answer format\n\t\t\t\t\tconst questionSuffix =\n\t\t\t\t\t\toptions.systemPromptTemplate === undefined ? '\\n\\nQuestion: {input}\\nAnswer:' : '';\n\n\t\t\t\t\tpromptTemplate = new PromptTemplate({\n\t\t\t\t\t\ttemplate: templateText + questionSuffix,\n\t\t\t\t\t\tinputVariables: ['context', 'input'],\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Create the document chain that combines the retrieved documents\n\t\t\t\tconst combineDocsChain = await createStuffDocumentsChain({\n\t\t\t\t\tllm: model,\n\t\t\t\t\tprompt: promptTemplate,\n\t\t\t\t});\n\n\t\t\t\t// Create the retrieval chain that handles the retrieval and then passes to the combine docs chain\n\t\t\t\tconst retrievalChain = await createRetrievalChain({\n\t\t\t\t\tcombineDocsChain,\n\t\t\t\t\tretriever,\n\t\t\t\t});\n\n\t\t\t\t// Execute the chain with tracing config\n\t\t\t\tconst tracingConfig = getTracingConfig(this);\n\t\t\t\tconst response = await retrievalChain\n\t\t\t\t\t.withConfig(tracingConfig)\n\t\t\t\t\t.invoke({ input: query }, { signal: this.getExecutionCancelSignal() });\n\n\t\t\t\t// Get the answer from the response\n\t\t\t\tconst answer: string = response.answer;\n\t\t\t\tif (this.getNode().typeVersion >= 1.5) {\n\t\t\t\t\treturnData.push({ json: { response: answer } });\n\t\t\t\t} else {\n\t\t\t\t\t// Legacy format for versions 1.4 and below is { text: string }\n\t\t\t\t\treturnData.push({ json: { response: { text: answer } } });\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\tconst metadata = parseErrorMetadata(error);\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -303,29 +303,6 @@ class ChainSummarizationV2 {
|
|
|
303
303
|
]
|
|
304
304
|
}
|
|
305
305
|
]
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
displayName: "Batch Processing",
|
|
309
|
-
name: "batching",
|
|
310
|
-
type: "collection",
|
|
311
|
-
description: "Batch processing options for rate limiting",
|
|
312
|
-
default: {},
|
|
313
|
-
options: [
|
|
314
|
-
{
|
|
315
|
-
displayName: "Batch Size",
|
|
316
|
-
name: "batchSize",
|
|
317
|
-
default: 100,
|
|
318
|
-
type: "number",
|
|
319
|
-
description: "How many items to process in parallel. This is useful for rate limiting."
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
displayName: "Delay Between Batches",
|
|
323
|
-
name: "delayBetweenBatches",
|
|
324
|
-
default: 0,
|
|
325
|
-
type: "number",
|
|
326
|
-
description: "Delay in milliseconds between batches. This is useful for rate limiting."
|
|
327
|
-
}
|
|
328
|
-
]
|
|
329
306
|
}
|
|
330
307
|
]
|
|
331
308
|
}
|
|
@@ -338,14 +315,8 @@ class ChainSummarizationV2 {
|
|
|
338
315
|
const chunkingMode = this.getNodeParameter("chunkingMode", 0, "simple");
|
|
339
316
|
const items = this.getInputData();
|
|
340
317
|
const returnData = [];
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
delayBetweenBatches: 0
|
|
344
|
-
});
|
|
345
|
-
for (let i = 0; i < items.length; i += batchSize) {
|
|
346
|
-
const batch = items.slice(i, i + batchSize);
|
|
347
|
-
const batchPromises = batch.map(async (_item, batchIndex) => {
|
|
348
|
-
const itemIndex = i + batchIndex;
|
|
318
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
319
|
+
try {
|
|
349
320
|
const model = await this.getInputConnectionData(
|
|
350
321
|
import_n8n_workflow.NodeConnectionTypes.AiLanguageModel,
|
|
351
322
|
0
|
|
@@ -362,7 +333,6 @@ class ChainSummarizationV2 {
|
|
|
362
333
|
const chain = (0, import_chains.loadSummarizationChain)(model, chainArgs);
|
|
363
334
|
const item = items[itemIndex];
|
|
364
335
|
let processedDocuments;
|
|
365
|
-
let output = {};
|
|
366
336
|
if (operationMode === "documentLoader") {
|
|
367
337
|
const documentInput = await this.getInputConnectionData(
|
|
368
338
|
import_n8n_workflow.NodeConnectionTypes.AiDocument,
|
|
@@ -370,9 +340,10 @@ class ChainSummarizationV2 {
|
|
|
370
340
|
);
|
|
371
341
|
const isN8nLoader = documentInput instanceof import_N8nJsonLoader.N8nJsonLoader || documentInput instanceof import_N8nBinaryLoader.N8nBinaryLoader;
|
|
372
342
|
processedDocuments = isN8nLoader ? await documentInput.processItem(item, itemIndex) : documentInput;
|
|
373
|
-
|
|
343
|
+
const response = await chain.withConfig((0, import_tracing.getTracingConfig)(this)).invoke({
|
|
374
344
|
input_documents: processedDocuments
|
|
375
345
|
});
|
|
346
|
+
returnData.push({ json: { response } });
|
|
376
347
|
}
|
|
377
348
|
if (["nodeInputJson", "nodeInputBinary"].includes(operationMode)) {
|
|
378
349
|
let textSplitter;
|
|
@@ -405,34 +376,20 @@ class ChainSummarizationV2 {
|
|
|
405
376
|
processor = new import_N8nJsonLoader.N8nJsonLoader(this, "options.", textSplitter);
|
|
406
377
|
}
|
|
407
378
|
const processedItem = await processor.processItem(item, itemIndex);
|
|
408
|
-
|
|
379
|
+
const response = await chain.invoke(
|
|
409
380
|
{
|
|
410
381
|
input_documents: processedItem
|
|
411
382
|
},
|
|
412
383
|
{ signal: this.getExecutionCancelSignal() }
|
|
413
384
|
);
|
|
385
|
+
returnData.push({ json: { response } });
|
|
414
386
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (response.status === "rejected") {
|
|
420
|
-
const error = response.reason;
|
|
421
|
-
if (this.continueOnFail()) {
|
|
422
|
-
returnData.push({
|
|
423
|
-
json: { error: error.message },
|
|
424
|
-
pairedItem: { item: i + index }
|
|
425
|
-
});
|
|
426
|
-
} else {
|
|
427
|
-
throw error;
|
|
428
|
-
}
|
|
429
|
-
} else {
|
|
430
|
-
const output = response.value;
|
|
431
|
-
returnData.push({ json: { output } });
|
|
387
|
+
} catch (error) {
|
|
388
|
+
if (this.continueOnFail()) {
|
|
389
|
+
returnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });
|
|
390
|
+
continue;
|
|
432
391
|
}
|
|
433
|
-
|
|
434
|
-
if (i + batchSize < items.length && delayBetweenBatches > 0) {
|
|
435
|
-
await (0, import_n8n_workflow.sleep)(delayBetweenBatches);
|
|
392
|
+
throw error;
|
|
436
393
|
}
|
|
437
394
|
}
|
|
438
395
|
return [returnData];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { ChainValues } from '@langchain/core/utils/types';\nimport type { TextSplitter } from '@langchain/textsplitters';\nimport { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';\nimport { loadSummarizationChain } from 'langchain/chains';\nimport type {\n\tINodeTypeBaseDescription,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n\tIDataObject,\n\tINodeInputConfiguration,\n} from 'n8n-workflow';\nimport { NodeConnectionTypes, sleep } from 'n8n-workflow';\n\nimport { N8nBinaryLoader } from '@utils/N8nBinaryLoader';\nimport { N8nJsonLoader } from '@utils/N8nJsonLoader';\nimport { getTemplateNoticeField } from '@utils/sharedFields';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { getChainPromptsArgs } from '../helpers';\nimport { REFINE_PROMPT_TEMPLATE, DEFAULT_PROMPT_TEMPLATE } from '../prompt';\n\nfunction getInputs(parameters: IDataObject) {\n\tconst chunkingMode = parameters?.chunkingMode;\n\tconst operationMode = parameters?.operationMode;\n\tconst inputs: INodeInputConfiguration[] = [\n\t\t{ displayName: '', type: 'main' },\n\t\t{\n\t\t\tdisplayName: 'Model',\n\t\t\tmaxConnections: 1,\n\t\t\ttype: 'ai_languageModel',\n\t\t\trequired: true,\n\t\t},\n\t];\n\n\tif (operationMode === 'documentLoader') {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Document',\n\t\t\ttype: 'ai_document',\n\t\t\trequired: true,\n\t\t\tmaxConnections: 1,\n\t\t});\n\t\treturn inputs;\n\t}\n\n\tif (chunkingMode === 'advanced') {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Text Splitter',\n\t\t\ttype: 'ai_textSplitter',\n\t\t\trequired: false,\n\t\t\tmaxConnections: 1,\n\t\t});\n\t\treturn inputs;\n\t}\n\treturn inputs;\n}\n\nexport class ChainSummarizationV2 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\tversion: [2],\n\t\t\tdefaults: {\n\t\t\t\tname: 'Summarization Chain',\n\t\t\t\tcolor: '#909298',\n\t\t\t},\n\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\t\tinputs: `={{ ((parameter) => { ${getInputs.toString()}; return getInputs(parameter) })($parameter) }}`,\n\t\t\toutputs: [NodeConnectionTypes.Main],\n\t\t\tcredentials: [],\n\t\t\tproperties: [\n\t\t\t\tgetTemplateNoticeField(1951),\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Data to Summarize',\n\t\t\t\t\tname: 'operationMode',\n\t\t\t\t\tnoDataExpression: true,\n\t\t\t\t\ttype: 'options',\n\t\t\t\t\tdescription: 'How to pass data into the summarization chain',\n\t\t\t\t\tdefault: 'nodeInputJson',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Use Node Input (JSON)',\n\t\t\t\t\t\t\tvalue: 'nodeInputJson',\n\t\t\t\t\t\t\tdescription: 'Summarize the JSON data coming into this node from the previous one',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Use Node Input (Binary)',\n\t\t\t\t\t\t\tvalue: 'nodeInputBinary',\n\t\t\t\t\t\t\tdescription: 'Summarize the binary data coming into this node from the previous one',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Use Document Loader',\n\t\t\t\t\t\t\tvalue: 'documentLoader',\n\t\t\t\t\t\t\tdescription: 'Use a loader sub-node with more configuration options',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Chunking Strategy',\n\t\t\t\t\tname: 'chunkingMode',\n\t\t\t\t\tnoDataExpression: true,\n\t\t\t\t\ttype: 'options',\n\t\t\t\t\tdescription: 'Chunk splitting strategy',\n\t\t\t\t\tdefault: 'simple',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Simple (Define Below)',\n\t\t\t\t\t\t\tvalue: 'simple',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Advanced',\n\t\t\t\t\t\t\tvalue: 'advanced',\n\t\t\t\t\t\t\tdescription: 'Use a splitter sub-node with more configuration options',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'/operationMode': ['nodeInputJson', 'nodeInputBinary'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Characters Per Chunk',\n\t\t\t\t\tname: 'chunkSize',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Controls the max size (in terms of number of characters) of the final document chunk',\n\t\t\t\t\ttype: 'number',\n\t\t\t\t\tdefault: 1000,\n\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'/chunkingMode': ['simple'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Chunk Overlap (Characters)',\n\t\t\t\t\tname: 'chunkOverlap',\n\t\t\t\t\ttype: 'number',\n\t\t\t\t\tdescription: 'Specifies how much characters overlap there should be between chunks',\n\t\t\t\t\tdefault: 200,\n\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'/chunkingMode': ['simple'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Options',\n\t\t\t\t\tname: 'options',\n\t\t\t\t\ttype: 'collection',\n\t\t\t\t\tdefault: {},\n\t\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Input Data Field Name',\n\t\t\t\t\t\t\tname: 'binaryDataKey',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdefault: 'data',\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'The name of the field in the agent or chain’s input that contains the binary file to be processed',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/operationMode': ['nodeInputBinary'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Summarization Method and Prompts',\n\t\t\t\t\t\t\tname: 'summarizationMethodAndPrompts',\n\t\t\t\t\t\t\ttype: 'fixedCollection',\n\t\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t\tvalues: {\n\t\t\t\t\t\t\t\t\tsummarizationMethod: 'map_reduce',\n\t\t\t\t\t\t\t\t\tprompt: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\tcombineMapPrompt: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\t\t\t\ttypeOptions: {},\n\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: 'values',\n\t\t\t\t\t\t\t\t\tdisplayName: 'Values',\n\t\t\t\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Summarization Method',\n\t\t\t\t\t\t\t\t\t\t\tname: 'summarizationMethod',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\t\t\t\tdescription: 'The type of summarization to run',\n\t\t\t\t\t\t\t\t\t\t\tdefault: 'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: 'Map Reduce (Recommended)',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: 'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Summarize each document (or chunk) individually, then summarize those summaries',\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: 'Refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: 'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Summarize the first document (or chunk). Then update that summary based on the next document (or chunk), and repeat.',\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: 'Stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: 'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pass all documents (or chunks) at once. Ideal for small datasets.',\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Individual Summary Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'combineMapPrompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt to summarize an individual document (or chunk)',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Final Prompt to Combine',\n\t\t\t\t\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt to combine individual summaries',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Subsequent (Refine) Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'refinePrompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tdefault: REFINE_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt to refine the summary based on the next document (or chunk)',\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Initial Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'refineQuestionPrompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt for the first document (or chunk)',\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Batch Processing',\n\t\t\t\t\t\t\tname: 'batching',\n\t\t\t\t\t\t\ttype: 'collection',\n\t\t\t\t\t\t\tdescription: 'Batch processing options for rate limiting',\n\t\t\t\t\t\t\tdefault: {},\n\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdisplayName: 'Batch Size',\n\t\t\t\t\t\t\t\t\tname: 'batchSize',\n\t\t\t\t\t\t\t\t\tdefault: 100,\n\t\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t'How many items to process in parallel. This is useful for rate limiting.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdisplayName: 'Delay Between Batches',\n\t\t\t\t\t\t\t\t\tname: 'delayBetweenBatches',\n\t\t\t\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t'Delay in milliseconds between batches. This is useful for rate limiting.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Summarization Chain V2');\n\t\tconst operationMode = this.getNodeParameter('operationMode', 0, 'nodeInputJson') as\n\t\t\t| 'nodeInputJson'\n\t\t\t| 'nodeInputBinary'\n\t\t\t| 'documentLoader';\n\t\tconst chunkingMode = this.getNodeParameter('chunkingMode', 0, 'simple') as\n\t\t\t| 'simple'\n\t\t\t| 'advanced';\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tconst { batchSize, delayBetweenBatches } = this.getNodeParameter('options.batching', 0, {\n\t\t\tbatchSize: 100,\n\t\t\tdelayBetweenBatches: 0,\n\t\t}) as {\n\t\t\tbatchSize: number;\n\t\t\tdelayBetweenBatches: number;\n\t\t};\n\n\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\tconst batchPromises = batch.map(async (_item, batchIndex) => {\n\t\t\t\tconst itemIndex = i + batchIndex;\n\n\t\t\t\tconst model = (await this.getInputConnectionData(\n\t\t\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t\t\t0,\n\t\t\t\t)) as BaseLanguageModel;\n\n\t\t\t\tconst summarizationMethodAndPrompts = this.getNodeParameter(\n\t\t\t\t\t'options.summarizationMethodAndPrompts.values',\n\t\t\t\t\titemIndex,\n\t\t\t\t\t{},\n\t\t\t\t) as {\n\t\t\t\t\tprompt?: string;\n\t\t\t\t\trefineQuestionPrompt?: string;\n\t\t\t\t\trefinePrompt?: string;\n\t\t\t\t\tsummarizationMethod: 'map_reduce' | 'stuff' | 'refine';\n\t\t\t\t\tcombineMapPrompt?: string;\n\t\t\t\t};\n\n\t\t\t\tconst chainArgs = getChainPromptsArgs(\n\t\t\t\t\tsummarizationMethodAndPrompts.summarizationMethod ?? 'map_reduce',\n\t\t\t\t\tsummarizationMethodAndPrompts,\n\t\t\t\t);\n\n\t\t\t\tconst chain = loadSummarizationChain(model, chainArgs);\n\t\t\t\tconst item = items[itemIndex];\n\n\t\t\t\tlet processedDocuments: Document[];\n\t\t\t\tlet output: ChainValues = {};\n\n\t\t\t\t// Use dedicated document loader input to load documents\n\t\t\t\tif (operationMode === 'documentLoader') {\n\t\t\t\t\tconst documentInput = (await this.getInputConnectionData(\n\t\t\t\t\t\tNodeConnectionTypes.AiDocument,\n\t\t\t\t\t\t0,\n\t\t\t\t\t)) as N8nJsonLoader | Array<Document<Record<string, unknown>>>;\n\n\t\t\t\t\tconst isN8nLoader =\n\t\t\t\t\t\tdocumentInput instanceof N8nJsonLoader || documentInput instanceof N8nBinaryLoader;\n\n\t\t\t\t\tprocessedDocuments = isN8nLoader\n\t\t\t\t\t\t? await documentInput.processItem(item, itemIndex)\n\t\t\t\t\t\t: documentInput;\n\n\t\t\t\t\toutput = await chain.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\t\tinput_documents: processedDocuments,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Take the input and use binary or json loader\n\t\t\t\tif (['nodeInputJson', 'nodeInputBinary'].includes(operationMode)) {\n\t\t\t\t\tlet textSplitter: TextSplitter | undefined;\n\n\t\t\t\t\tswitch (chunkingMode) {\n\t\t\t\t\t\t// In simple mode we use recursive character splitter with default settings\n\t\t\t\t\t\tcase 'simple':\n\t\t\t\t\t\t\tconst chunkSize = this.getNodeParameter('chunkSize', itemIndex, 1000) as number;\n\t\t\t\t\t\t\tconst chunkOverlap = this.getNodeParameter('chunkOverlap', itemIndex, 200) as number;\n\n\t\t\t\t\t\t\ttextSplitter = new RecursiveCharacterTextSplitter({ chunkOverlap, chunkSize });\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t// In advanced mode user can connect text splitter node so we just retrieve it\n\t\t\t\t\t\tcase 'advanced':\n\t\t\t\t\t\t\ttextSplitter = (await this.getInputConnectionData(\n\t\t\t\t\t\t\t\tNodeConnectionTypes.AiTextSplitter,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t)) as TextSplitter | undefined;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet processor: N8nJsonLoader | N8nBinaryLoader;\n\t\t\t\t\tif (operationMode === 'nodeInputBinary') {\n\t\t\t\t\t\tconst binaryDataKey = this.getNodeParameter(\n\t\t\t\t\t\t\t'options.binaryDataKey',\n\t\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\t\t'data',\n\t\t\t\t\t\t) as string;\n\t\t\t\t\t\tprocessor = new N8nBinaryLoader(this, 'options.', binaryDataKey, textSplitter);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprocessor = new N8nJsonLoader(this, 'options.', textSplitter);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst processedItem = await processor.processItem(item, itemIndex);\n\t\t\t\t\toutput = await chain.invoke(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinput_documents: processedItem,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ signal: this.getExecutionCancelSignal() },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn output;\n\t\t\t});\n\n\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\tconst error = response.reason as Error;\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\tpairedItem: { item: i + index },\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst output = response.value;\n\t\t\t\t\treturnData.push({ json: { output } });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Add delay between batches if not the last batch\n\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,2BAA+C;AAC/C,oBAAuC;AAUvC,0BAA2C;AAE3C,6BAAgC;AAChC,2BAA8B;AAC9B,0BAAuC;AACvC,qBAAiC;AAEjC,qBAAoC;AACpC,oBAAgE;AAEhE,SAAS,UAAU,YAAyB;AAC3C,QAAM,eAAe,YAAY;AACjC,QAAM,gBAAgB,YAAY;AAClC,QAAM,SAAoC;AAAA,IACzC,EAAE,aAAa,IAAI,MAAM,OAAO;AAAA,IAChC;AAAA,MACC,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,MAAM;AAAA,MACN,UAAU;AAAA,IACX;AAAA,EACD;AAEA,MAAI,kBAAkB,kBAAkB;AACvC,WAAO,KAAK;AAAA,MACX,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,gBAAgB;AAAA,IACjB,CAAC;AACD,WAAO;AAAA,EACR;AAEA,MAAI,iBAAiB,YAAY;AAChC,WAAO,KAAK;AAAA,MACX,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,gBAAgB;AAAA,IACjB,CAAC;AACD,WAAO;AAAA,EACR;AACA,SAAO;AACR;AAEO,MAAM,qBAA0C;AAAA,EAGtD,YAAY,iBAA2C;AACtD,SAAK,cAAc;AAAA,MAClB,GAAG;AAAA,MACH,SAAS,CAAC,CAAC;AAAA,MACX,UAAU;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA;AAAA,MAEA,QAAQ,yBAAyB,UAAU,SAAS,CAAC;AAAA,MACrD,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,aAAa,CAAC;AAAA,MACd,YAAY;AAAA,YACX,4CAAuB,IAAI;AAAA,QAC3B;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,UACD;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,kBAAkB,CAAC,iBAAiB,iBAAiB;AAAA,YACtD;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aACC;AAAA,UACD,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,iBAAiB,CAAC,QAAQ;AAAA,YAC3B;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,iBAAiB,CAAC,QAAQ;AAAA,YAC3B;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,aAAa;AAAA,UACb,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,kBAAkB,CAAC,iBAAiB;AAAA,gBACrC;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,gBACR,QAAQ;AAAA,kBACP,qBAAqB;AAAA,kBACrB,QAAQ;AAAA,kBACR,kBAAkB;AAAA,gBACnB;AAAA,cACD;AAAA,cACA,aAAa;AAAA,cACb,aAAa,CAAC;AAAA,cACd,SAAS;AAAA,gBACR;AAAA,kBACC,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,QAAQ;AAAA,oBACP;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,aAAa;AAAA,sBACb,SAAS;AAAA,sBACT,SAAS;AAAA,wBACR;AAAA,0BACC,MAAM;AAAA,0BACN,OAAO;AAAA,0BACP,aACC;AAAA,wBACF;AAAA,wBACA;AAAA,0BACC,MAAM;AAAA,0BACN,OAAO;AAAA,0BACP,aACC;AAAA,wBACF;AAAA,wBACA;AAAA,0BACC,MAAM;AAAA,0BACN,OAAO;AAAA,0BACP,aACC;AAAA,wBACF;AAAA,sBACD;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,SAAS;AAAA,sBACT,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,SAAS;AAAA,sBACT,MAAM;AAAA,sBACN,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,SAAS;AAAA,sBACT,MAAM;AAAA,sBACN,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,kBACD;AAAA,gBACD;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,SAAS,CAAC;AAAA,cACV,SAAS;AAAA,gBACR;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,aACC;AAAA,gBACF;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,aACC;AAAA,gBACF;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAM,UAAkE;AACvE,SAAK,OAAO,MAAM,kCAAkC;AACpD,UAAM,gBAAgB,KAAK,iBAAiB,iBAAiB,GAAG,eAAe;AAI/E,UAAM,eAAe,KAAK,iBAAiB,gBAAgB,GAAG,QAAQ;AAItE,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,aAAmC,CAAC;AAC1C,UAAM,EAAE,WAAW,oBAAoB,IAAI,KAAK,iBAAiB,oBAAoB,GAAG;AAAA,MACvF,WAAW;AAAA,MACX,qBAAqB;AAAA,IACtB,CAAC;AAKD,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,WAAW;AACjD,YAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,SAAS;AAC1C,YAAM,gBAAgB,MAAM,IAAI,OAAO,OAAO,eAAe;AAC5D,cAAM,YAAY,IAAI;AAEtB,cAAM,QAAS,MAAM,KAAK;AAAA,UACzB,wCAAoB;AAAA,UACpB;AAAA,QACD;AAEA,cAAM,gCAAgC,KAAK;AAAA,UAC1C;AAAA,UACA;AAAA,UACA,CAAC;AAAA,QACF;AAQA,cAAM,gBAAY;AAAA,UACjB,8BAA8B,uBAAuB;AAAA,UACrD;AAAA,QACD;AAEA,cAAM,YAAQ,sCAAuB,OAAO,SAAS;AACrD,cAAM,OAAO,MAAM,SAAS;AAE5B,YAAI;AACJ,YAAI,SAAsB,CAAC;AAG3B,YAAI,kBAAkB,kBAAkB;AACvC,gBAAM,gBAAiB,MAAM,KAAK;AAAA,YACjC,wCAAoB;AAAA,YACpB;AAAA,UACD;AAEA,gBAAM,cACL,yBAAyB,sCAAiB,yBAAyB;AAEpE,+BAAqB,cAClB,MAAM,cAAc,YAAY,MAAM,SAAS,IAC/C;AAEH,mBAAS,MAAM,MAAM,eAAW,iCAAiB,IAAI,CAAC,EAAE,OAAO;AAAA,YAC9D,iBAAiB;AAAA,UAClB,CAAC;AAAA,QACF;AAGA,YAAI,CAAC,iBAAiB,iBAAiB,EAAE,SAAS,aAAa,GAAG;AACjE,cAAI;AAEJ,kBAAQ,cAAc;AAAA;AAAA,YAErB,KAAK;AACJ,oBAAM,YAAY,KAAK,iBAAiB,aAAa,WAAW,GAAI;AACpE,oBAAM,eAAe,KAAK,iBAAiB,gBAAgB,WAAW,GAAG;AAEzE,6BAAe,IAAI,oDAA+B,EAAE,cAAc,UAAU,CAAC;AAC7E;AAAA;AAAA,YAGD,KAAK;AACJ,6BAAgB,MAAM,KAAK;AAAA,gBAC1B,wCAAoB;AAAA,gBACpB;AAAA,cACD;AACA;AAAA,YACD;AACC;AAAA,UACF;AAEA,cAAI;AACJ,cAAI,kBAAkB,mBAAmB;AACxC,kBAAM,gBAAgB,KAAK;AAAA,cAC1B;AAAA,cACA;AAAA,cACA;AAAA,YACD;AACA,wBAAY,IAAI,uCAAgB,MAAM,YAAY,eAAe,YAAY;AAAA,UAC9E,OAAO;AACN,wBAAY,IAAI,mCAAc,MAAM,YAAY,YAAY;AAAA,UAC7D;AAEA,gBAAM,gBAAgB,MAAM,UAAU,YAAY,MAAM,SAAS;AACjE,mBAAS,MAAM,MAAM;AAAA,YACpB;AAAA,cACC,iBAAiB;AAAA,YAClB;AAAA,YACA,EAAE,QAAQ,KAAK,yBAAyB,EAAE;AAAA,UAC3C;AAAA,QACD;AACA,eAAO;AAAA,MACR,CAAC;AAED,YAAM,eAAe,MAAM,QAAQ,WAAW,aAAa;AAC3D,mBAAa,QAAQ,CAAC,UAAU,UAAU;AACzC,YAAI,SAAS,WAAW,YAAY;AACnC,gBAAM,QAAQ,SAAS;AACvB,cAAI,KAAK,eAAe,GAAG;AAC1B,uBAAW,KAAK;AAAA,cACf,MAAM,EAAE,OAAO,MAAM,QAAQ;AAAA,cAC7B,YAAY,EAAE,MAAM,IAAI,MAAM;AAAA,YAC/B,CAAC;AAAA,UACF,OAAO;AACN,kBAAM;AAAA,UACP;AAAA,QACD,OAAO;AACN,gBAAM,SAAS,SAAS;AACxB,qBAAW,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,QACrC;AAAA,MACD,CAAC;AAGD,UAAI,IAAI,YAAY,MAAM,UAAU,sBAAsB,GAAG;AAC5D,kBAAM,2BAAM,mBAAmB;AAAA,MAChC;AAAA,IACD;AAEA,WAAO,CAAC,UAAU;AAAA,EACnB;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { TextSplitter } from '@langchain/textsplitters';\nimport { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';\nimport { loadSummarizationChain } from 'langchain/chains';\nimport type {\n\tINodeTypeBaseDescription,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n\tIDataObject,\n\tINodeInputConfiguration,\n} from 'n8n-workflow';\nimport { NodeConnectionTypes } from 'n8n-workflow';\n\nimport { N8nBinaryLoader } from '@utils/N8nBinaryLoader';\nimport { N8nJsonLoader } from '@utils/N8nJsonLoader';\nimport { getTemplateNoticeField } from '@utils/sharedFields';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { getChainPromptsArgs } from '../helpers';\nimport { REFINE_PROMPT_TEMPLATE, DEFAULT_PROMPT_TEMPLATE } from '../prompt';\n\nfunction getInputs(parameters: IDataObject) {\n\tconst chunkingMode = parameters?.chunkingMode;\n\tconst operationMode = parameters?.operationMode;\n\tconst inputs: INodeInputConfiguration[] = [\n\t\t{ displayName: '', type: 'main' },\n\t\t{\n\t\t\tdisplayName: 'Model',\n\t\t\tmaxConnections: 1,\n\t\t\ttype: 'ai_languageModel',\n\t\t\trequired: true,\n\t\t},\n\t];\n\n\tif (operationMode === 'documentLoader') {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Document',\n\t\t\ttype: 'ai_document',\n\t\t\trequired: true,\n\t\t\tmaxConnections: 1,\n\t\t});\n\t\treturn inputs;\n\t}\n\n\tif (chunkingMode === 'advanced') {\n\t\tinputs.push({\n\t\t\tdisplayName: 'Text Splitter',\n\t\t\ttype: 'ai_textSplitter',\n\t\t\trequired: false,\n\t\t\tmaxConnections: 1,\n\t\t});\n\t\treturn inputs;\n\t}\n\treturn inputs;\n}\n\nexport class ChainSummarizationV2 implements INodeType {\n\tdescription: INodeTypeDescription;\n\n\tconstructor(baseDescription: INodeTypeBaseDescription) {\n\t\tthis.description = {\n\t\t\t...baseDescription,\n\t\t\tversion: [2],\n\t\t\tdefaults: {\n\t\t\t\tname: 'Summarization Chain',\n\t\t\t\tcolor: '#909298',\n\t\t\t},\n\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node\n\t\t\tinputs: `={{ ((parameter) => { ${getInputs.toString()}; return getInputs(parameter) })($parameter) }}`,\n\t\t\toutputs: [NodeConnectionTypes.Main],\n\t\t\tcredentials: [],\n\t\t\tproperties: [\n\t\t\t\tgetTemplateNoticeField(1951),\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Data to Summarize',\n\t\t\t\t\tname: 'operationMode',\n\t\t\t\t\tnoDataExpression: true,\n\t\t\t\t\ttype: 'options',\n\t\t\t\t\tdescription: 'How to pass data into the summarization chain',\n\t\t\t\t\tdefault: 'nodeInputJson',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Use Node Input (JSON)',\n\t\t\t\t\t\t\tvalue: 'nodeInputJson',\n\t\t\t\t\t\t\tdescription: 'Summarize the JSON data coming into this node from the previous one',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Use Node Input (Binary)',\n\t\t\t\t\t\t\tvalue: 'nodeInputBinary',\n\t\t\t\t\t\t\tdescription: 'Summarize the binary data coming into this node from the previous one',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Use Document Loader',\n\t\t\t\t\t\t\tvalue: 'documentLoader',\n\t\t\t\t\t\t\tdescription: 'Use a loader sub-node with more configuration options',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Chunking Strategy',\n\t\t\t\t\tname: 'chunkingMode',\n\t\t\t\t\tnoDataExpression: true,\n\t\t\t\t\ttype: 'options',\n\t\t\t\t\tdescription: 'Chunk splitting strategy',\n\t\t\t\t\tdefault: 'simple',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Simple (Define Below)',\n\t\t\t\t\t\t\tvalue: 'simple',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Advanced',\n\t\t\t\t\t\t\tvalue: 'advanced',\n\t\t\t\t\t\t\tdescription: 'Use a splitter sub-node with more configuration options',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'/operationMode': ['nodeInputJson', 'nodeInputBinary'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Characters Per Chunk',\n\t\t\t\t\tname: 'chunkSize',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Controls the max size (in terms of number of characters) of the final document chunk',\n\t\t\t\t\ttype: 'number',\n\t\t\t\t\tdefault: 1000,\n\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'/chunkingMode': ['simple'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Chunk Overlap (Characters)',\n\t\t\t\t\tname: 'chunkOverlap',\n\t\t\t\t\ttype: 'number',\n\t\t\t\t\tdescription: 'Specifies how much characters overlap there should be between chunks',\n\t\t\t\t\tdefault: 200,\n\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'/chunkingMode': ['simple'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Options',\n\t\t\t\t\tname: 'options',\n\t\t\t\t\ttype: 'collection',\n\t\t\t\t\tdefault: {},\n\t\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Input Data Field Name',\n\t\t\t\t\t\t\tname: 'binaryDataKey',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\tdefault: 'data',\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t'The name of the field in the agent or chain’s input that contains the binary file to be processed',\n\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t'/operationMode': ['nodeInputBinary'],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdisplayName: 'Summarization Method and Prompts',\n\t\t\t\t\t\t\tname: 'summarizationMethodAndPrompts',\n\t\t\t\t\t\t\ttype: 'fixedCollection',\n\t\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t\tvalues: {\n\t\t\t\t\t\t\t\t\tsummarizationMethod: 'map_reduce',\n\t\t\t\t\t\t\t\t\tprompt: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\tcombineMapPrompt: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\t\t\t\ttypeOptions: {},\n\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: 'values',\n\t\t\t\t\t\t\t\t\tdisplayName: 'Values',\n\t\t\t\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Summarization Method',\n\t\t\t\t\t\t\t\t\t\t\tname: 'summarizationMethod',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\t\t\t\tdescription: 'The type of summarization to run',\n\t\t\t\t\t\t\t\t\t\t\tdefault: 'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: 'Map Reduce (Recommended)',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: 'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Summarize each document (or chunk) individually, then summarize those summaries',\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: 'Refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: 'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Summarize the first document (or chunk). Then update that summary based on the next document (or chunk), and repeat.',\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: 'Stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: 'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pass all documents (or chunks) at once. Ideal for small datasets.',\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Individual Summary Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'combineMapPrompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt to summarize an individual document (or chunk)',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Final Prompt to Combine',\n\t\t\t\t\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt to combine individual summaries',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'prompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'refine',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Subsequent (Refine) Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'refinePrompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tdefault: REFINE_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt to refine the summary based on the next document (or chunk)',\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tdisplayName: 'Initial Prompt',\n\t\t\t\t\t\t\t\t\t\t\tname: 'refineQuestionPrompt',\n\t\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t'/options.summarizationMethodAndPrompts.values.summarizationMethod': [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'stuff',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'map_reduce',\n\t\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tdefault: DEFAULT_PROMPT_TEMPLATE,\n\t\t\t\t\t\t\t\t\t\t\thint: 'The prompt for the first document (or chunk)',\n\t\t\t\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\t\t\t\trows: 9,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Summarization Chain V2');\n\t\tconst operationMode = this.getNodeParameter('operationMode', 0, 'nodeInputJson') as\n\t\t\t| 'nodeInputJson'\n\t\t\t| 'nodeInputBinary'\n\t\t\t| 'documentLoader';\n\t\tconst chunkingMode = this.getNodeParameter('chunkingMode', 0, 'simple') as\n\t\t\t| 'simple'\n\t\t\t| 'advanced';\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst model = (await this.getInputConnectionData(\n\t\t\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t\t\t0,\n\t\t\t\t)) as BaseLanguageModel;\n\n\t\t\t\tconst summarizationMethodAndPrompts = this.getNodeParameter(\n\t\t\t\t\t'options.summarizationMethodAndPrompts.values',\n\t\t\t\t\titemIndex,\n\t\t\t\t\t{},\n\t\t\t\t) as {\n\t\t\t\t\tprompt?: string;\n\t\t\t\t\trefineQuestionPrompt?: string;\n\t\t\t\t\trefinePrompt?: string;\n\t\t\t\t\tsummarizationMethod: 'map_reduce' | 'stuff' | 'refine';\n\t\t\t\t\tcombineMapPrompt?: string;\n\t\t\t\t};\n\n\t\t\t\tconst chainArgs = getChainPromptsArgs(\n\t\t\t\t\tsummarizationMethodAndPrompts.summarizationMethod ?? 'map_reduce',\n\t\t\t\t\tsummarizationMethodAndPrompts,\n\t\t\t\t);\n\n\t\t\t\tconst chain = loadSummarizationChain(model, chainArgs);\n\t\t\t\tconst item = items[itemIndex];\n\n\t\t\t\tlet processedDocuments: Document[];\n\n\t\t\t\t// Use dedicated document loader input to load documents\n\t\t\t\tif (operationMode === 'documentLoader') {\n\t\t\t\t\tconst documentInput = (await this.getInputConnectionData(\n\t\t\t\t\t\tNodeConnectionTypes.AiDocument,\n\t\t\t\t\t\t0,\n\t\t\t\t\t)) as N8nJsonLoader | Array<Document<Record<string, unknown>>>;\n\n\t\t\t\t\tconst isN8nLoader =\n\t\t\t\t\t\tdocumentInput instanceof N8nJsonLoader || documentInput instanceof N8nBinaryLoader;\n\n\t\t\t\t\tprocessedDocuments = isN8nLoader\n\t\t\t\t\t\t? await documentInput.processItem(item, itemIndex)\n\t\t\t\t\t\t: documentInput;\n\n\t\t\t\t\tconst response = await chain.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\t\tinput_documents: processedDocuments,\n\t\t\t\t\t});\n\n\t\t\t\t\treturnData.push({ json: { response } });\n\t\t\t\t}\n\n\t\t\t\t// Take the input and use binary or json loader\n\t\t\t\tif (['nodeInputJson', 'nodeInputBinary'].includes(operationMode)) {\n\t\t\t\t\tlet textSplitter: TextSplitter | undefined;\n\n\t\t\t\t\tswitch (chunkingMode) {\n\t\t\t\t\t\t// In simple mode we use recursive character splitter with default settings\n\t\t\t\t\t\tcase 'simple':\n\t\t\t\t\t\t\tconst chunkSize = this.getNodeParameter('chunkSize', itemIndex, 1000) as number;\n\t\t\t\t\t\t\tconst chunkOverlap = this.getNodeParameter('chunkOverlap', itemIndex, 200) as number;\n\n\t\t\t\t\t\t\ttextSplitter = new RecursiveCharacterTextSplitter({ chunkOverlap, chunkSize });\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t// In advanced mode user can connect text splitter node so we just retrieve it\n\t\t\t\t\t\tcase 'advanced':\n\t\t\t\t\t\t\ttextSplitter = (await this.getInputConnectionData(\n\t\t\t\t\t\t\t\tNodeConnectionTypes.AiTextSplitter,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t)) as TextSplitter | undefined;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet processor: N8nJsonLoader | N8nBinaryLoader;\n\t\t\t\t\tif (operationMode === 'nodeInputBinary') {\n\t\t\t\t\t\tconst binaryDataKey = this.getNodeParameter(\n\t\t\t\t\t\t\t'options.binaryDataKey',\n\t\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\t\t'data',\n\t\t\t\t\t\t) as string;\n\t\t\t\t\t\tprocessor = new N8nBinaryLoader(this, 'options.', binaryDataKey, textSplitter);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprocessor = new N8nJsonLoader(this, 'options.', textSplitter);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst processedItem = await processor.processItem(item, itemIndex);\n\t\t\t\t\tconst response = await chain.invoke(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinput_documents: processedItem,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ signal: this.getExecutionCancelSignal() },\n\t\t\t\t\t);\n\t\t\t\t\treturnData.push({ json: { response } });\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,2BAA+C;AAC/C,oBAAuC;AAUvC,0BAAoC;AAEpC,6BAAgC;AAChC,2BAA8B;AAC9B,0BAAuC;AACvC,qBAAiC;AAEjC,qBAAoC;AACpC,oBAAgE;AAEhE,SAAS,UAAU,YAAyB;AAC3C,QAAM,eAAe,YAAY;AACjC,QAAM,gBAAgB,YAAY;AAClC,QAAM,SAAoC;AAAA,IACzC,EAAE,aAAa,IAAI,MAAM,OAAO;AAAA,IAChC;AAAA,MACC,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,MAAM;AAAA,MACN,UAAU;AAAA,IACX;AAAA,EACD;AAEA,MAAI,kBAAkB,kBAAkB;AACvC,WAAO,KAAK;AAAA,MACX,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,gBAAgB;AAAA,IACjB,CAAC;AACD,WAAO;AAAA,EACR;AAEA,MAAI,iBAAiB,YAAY;AAChC,WAAO,KAAK;AAAA,MACX,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,gBAAgB;AAAA,IACjB,CAAC;AACD,WAAO;AAAA,EACR;AACA,SAAO;AACR;AAEO,MAAM,qBAA0C;AAAA,EAGtD,YAAY,iBAA2C;AACtD,SAAK,cAAc;AAAA,MAClB,GAAG;AAAA,MACH,SAAS,CAAC,CAAC;AAAA,MACX,UAAU;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA;AAAA,MAEA,QAAQ,yBAAyB,UAAU,SAAS,CAAC;AAAA,MACrD,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,aAAa,CAAC;AAAA,MACd,YAAY;AAAA,YACX,4CAAuB,IAAI;AAAA,QAC3B;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,UACD;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,kBAAkB,CAAC,iBAAiB,iBAAiB;AAAA,YACtD;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aACC;AAAA,UACD,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,iBAAiB,CAAC,QAAQ;AAAA,YAC3B;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,iBAAiB,CAAC,QAAQ;AAAA,YAC3B;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,aAAa;AAAA,UACb,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,kBAAkB,CAAC,iBAAiB;AAAA,gBACrC;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,gBACR,QAAQ;AAAA,kBACP,qBAAqB;AAAA,kBACrB,QAAQ;AAAA,kBACR,kBAAkB;AAAA,gBACnB;AAAA,cACD;AAAA,cACA,aAAa;AAAA,cACb,aAAa,CAAC;AAAA,cACd,SAAS;AAAA,gBACR;AAAA,kBACC,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,QAAQ;AAAA,oBACP;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,aAAa;AAAA,sBACb,SAAS;AAAA,sBACT,SAAS;AAAA,wBACR;AAAA,0BACC,MAAM;AAAA,0BACN,OAAO;AAAA,0BACP,aACC;AAAA,wBACF;AAAA,wBACA;AAAA,0BACC,MAAM;AAAA,0BACN,OAAO;AAAA,0BACP,aACC;AAAA,wBACF;AAAA,wBACA;AAAA,0BACC,MAAM;AAAA,0BACN,OAAO;AAAA,0BACP,aACC;AAAA,wBACF;AAAA,sBACD;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,SAAS;AAAA,sBACT,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,SAAS;AAAA,sBACT,MAAM;AAAA,sBACN,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,qEAAqE;AAAA,4BACpE;AAAA,4BACA;AAAA,0BACD;AAAA,wBACD;AAAA,sBACD;AAAA,sBACA,SAAS;AAAA,sBACT,MAAM;AAAA,sBACN,aAAa;AAAA,wBACZ,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,kBACD;AAAA,gBACD;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAM,UAAkE;AACvE,SAAK,OAAO,MAAM,kCAAkC;AACpD,UAAM,gBAAgB,KAAK,iBAAiB,iBAAiB,GAAG,eAAe;AAI/E,UAAM,eAAe,KAAK,iBAAiB,gBAAgB,GAAG,QAAQ;AAItE,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,aAAmC,CAAC;AAE1C,aAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,UAAI;AACH,cAAM,QAAS,MAAM,KAAK;AAAA,UACzB,wCAAoB;AAAA,UACpB;AAAA,QACD;AAEA,cAAM,gCAAgC,KAAK;AAAA,UAC1C;AAAA,UACA;AAAA,UACA,CAAC;AAAA,QACF;AAQA,cAAM,gBAAY;AAAA,UACjB,8BAA8B,uBAAuB;AAAA,UACrD;AAAA,QACD;AAEA,cAAM,YAAQ,sCAAuB,OAAO,SAAS;AACrD,cAAM,OAAO,MAAM,SAAS;AAE5B,YAAI;AAGJ,YAAI,kBAAkB,kBAAkB;AACvC,gBAAM,gBAAiB,MAAM,KAAK;AAAA,YACjC,wCAAoB;AAAA,YACpB;AAAA,UACD;AAEA,gBAAM,cACL,yBAAyB,sCAAiB,yBAAyB;AAEpE,+BAAqB,cAClB,MAAM,cAAc,YAAY,MAAM,SAAS,IAC/C;AAEH,gBAAM,WAAW,MAAM,MAAM,eAAW,iCAAiB,IAAI,CAAC,EAAE,OAAO;AAAA,YACtE,iBAAiB;AAAA,UAClB,CAAC;AAED,qBAAW,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAAA,QACvC;AAGA,YAAI,CAAC,iBAAiB,iBAAiB,EAAE,SAAS,aAAa,GAAG;AACjE,cAAI;AAEJ,kBAAQ,cAAc;AAAA;AAAA,YAErB,KAAK;AACJ,oBAAM,YAAY,KAAK,iBAAiB,aAAa,WAAW,GAAI;AACpE,oBAAM,eAAe,KAAK,iBAAiB,gBAAgB,WAAW,GAAG;AAEzE,6BAAe,IAAI,oDAA+B,EAAE,cAAc,UAAU,CAAC;AAC7E;AAAA;AAAA,YAGD,KAAK;AACJ,6BAAgB,MAAM,KAAK;AAAA,gBAC1B,wCAAoB;AAAA,gBACpB;AAAA,cACD;AACA;AAAA,YACD;AACC;AAAA,UACF;AAEA,cAAI;AACJ,cAAI,kBAAkB,mBAAmB;AACxC,kBAAM,gBAAgB,KAAK;AAAA,cAC1B;AAAA,cACA;AAAA,cACA;AAAA,YACD;AACA,wBAAY,IAAI,uCAAgB,MAAM,YAAY,eAAe,YAAY;AAAA,UAC9E,OAAO;AACN,wBAAY,IAAI,mCAAc,MAAM,YAAY,YAAY;AAAA,UAC7D;AAEA,gBAAM,gBAAgB,MAAM,UAAU,YAAY,MAAM,SAAS;AACjE,gBAAM,WAAW,MAAM,MAAM;AAAA,YAC5B;AAAA,cACC,iBAAiB;AAAA,YAClB;AAAA,YACA,EAAE,QAAQ,KAAK,yBAAyB,EAAE;AAAA,UAC3C;AACA,qBAAW,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAAA,QACvC;AAAA,MACD,SAAS,OAAO;AACf,YAAI,KAAK,eAAe,GAAG;AAC1B,qBAAW,KAAK,EAAE,MAAM,EAAE,OAAO,MAAM,QAAQ,GAAG,YAAY,EAAE,MAAM,UAAU,EAAE,CAAC;AACnF;AAAA,QACD;AAEA,cAAM;AAAA,MACP;AAAA,IACD;AAEA,WAAO,CAAC,UAAU;AAAA,EACnB;AACD;","names":[]}
|
|
@@ -219,29 +219,6 @@ class InformationExtractor {
|
|
|
219
219
|
typeOptions: {
|
|
220
220
|
rows: 6
|
|
221
221
|
}
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
displayName: "Batch Processing",
|
|
225
|
-
name: "batching",
|
|
226
|
-
type: "collection",
|
|
227
|
-
description: "Batch processing options for rate limiting",
|
|
228
|
-
default: {},
|
|
229
|
-
options: [
|
|
230
|
-
{
|
|
231
|
-
displayName: "Batch Size",
|
|
232
|
-
name: "batchSize",
|
|
233
|
-
default: 100,
|
|
234
|
-
type: "number",
|
|
235
|
-
description: "How many items to process in parallel. This is useful for rate limiting, but will impact the agents log output."
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
displayName: "Delay Between Batches",
|
|
239
|
-
name: "delayBetweenBatches",
|
|
240
|
-
default: 0,
|
|
241
|
-
type: "number",
|
|
242
|
-
description: "Delay in milliseconds between batches. This is useful for rate limiting."
|
|
243
|
-
}
|
|
244
|
-
]
|
|
245
222
|
}
|
|
246
223
|
]
|
|
247
224
|
}
|
|
@@ -250,10 +227,6 @@ class InformationExtractor {
|
|
|
250
227
|
}
|
|
251
228
|
async execute() {
|
|
252
229
|
const items = this.getInputData();
|
|
253
|
-
const { batchSize, delayBetweenBatches } = this.getNodeParameter("options.batching", 0, {
|
|
254
|
-
batchSize: 100,
|
|
255
|
-
delayBetweenBatches: 0
|
|
256
|
-
});
|
|
257
230
|
const llm = await this.getInputConnectionData(
|
|
258
231
|
import_n8n_workflow.NodeConnectionTypes.AiLanguageModel,
|
|
259
232
|
0
|
|
@@ -286,46 +259,31 @@ class InformationExtractor {
|
|
|
286
259
|
parser = import_output_parsers.OutputFixingParser.fromLLM(llm, import_output_parsers.StructuredOutputParser.fromZodSchema(zodSchema));
|
|
287
260
|
}
|
|
288
261
|
const resultData = [];
|
|
289
|
-
for (let
|
|
290
|
-
const
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
const
|
|
307
|
-
const chain = prompt.pipe(llm).pipe(parser).withConfig((0, import_tracing.getTracingConfig)(this));
|
|
308
|
-
return await chain.invoke(messages);
|
|
309
|
-
});
|
|
310
|
-
const batchResults = await Promise.allSettled(batchPromises);
|
|
311
|
-
batchResults.forEach((response, index) => {
|
|
312
|
-
if (response.status === "rejected") {
|
|
313
|
-
const error = response.reason;
|
|
314
|
-
if (this.continueOnFail()) {
|
|
315
|
-
resultData.push({
|
|
316
|
-
json: { error: response.reason },
|
|
317
|
-
pairedItem: { item: i + index }
|
|
318
|
-
});
|
|
319
|
-
return;
|
|
320
|
-
} else {
|
|
321
|
-
throw new import_n8n_workflow.NodeOperationError(this.getNode(), error.message);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
const output = response.value;
|
|
262
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
263
|
+
const input = this.getNodeParameter("text", itemIndex);
|
|
264
|
+
const inputPrompt = new import_messages.HumanMessage(input);
|
|
265
|
+
const options = this.getNodeParameter("options", itemIndex, {});
|
|
266
|
+
const systemPromptTemplate = import_prompts.SystemMessagePromptTemplate.fromTemplate(
|
|
267
|
+
`${options.systemPromptTemplate ?? SYSTEM_PROMPT_TEMPLATE}
|
|
268
|
+
{format_instructions}`
|
|
269
|
+
);
|
|
270
|
+
const messages = [
|
|
271
|
+
await systemPromptTemplate.format({
|
|
272
|
+
format_instructions: parser.getFormatInstructions()
|
|
273
|
+
}),
|
|
274
|
+
inputPrompt
|
|
275
|
+
];
|
|
276
|
+
const prompt = import_prompts.ChatPromptTemplate.fromMessages(messages);
|
|
277
|
+
const chain = prompt.pipe(llm).pipe(parser).withConfig((0, import_tracing.getTracingConfig)(this));
|
|
278
|
+
try {
|
|
279
|
+
const output = await chain.invoke(messages);
|
|
325
280
|
resultData.push({ json: { output } });
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
|
|
281
|
+
} catch (error) {
|
|
282
|
+
if (this.continueOnFail()) {
|
|
283
|
+
resultData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
throw error;
|
|
329
287
|
}
|
|
330
288
|
}
|
|
331
289
|
return [resultData];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/chains/InformationExtractor/InformationExtractor.node.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { HumanMessage } from '@langchain/core/messages';\nimport { ChatPromptTemplate, SystemMessagePromptTemplate } from '@langchain/core/prompts';\nimport type { JSONSchema7 } from 'json-schema';\nimport { OutputFixingParser, StructuredOutputParser } from 'langchain/output_parsers';\nimport { jsonParse, NodeConnectionTypes, NodeOperationError, sleep } from 'n8n-workflow';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodePropertyOptions,\n} from 'n8n-workflow';\nimport type { z } from 'zod';\n\nimport { inputSchemaField, jsonSchemaExampleField, schemaTypeField } from '@utils/descriptions';\nimport { convertJsonSchemaToZod, generateSchema } from '@utils/schemaParsing';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { makeZodSchemaFromAttributes } from './helpers';\nimport type { AttributeDefinition } from './types';\n\nconst SYSTEM_PROMPT_TEMPLATE = `You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value.`;\n\nexport class InformationExtractor implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Information Extractor',\n\t\tname: 'informationExtractor',\n\t\ticon: 'fa:project-diagram',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Extract information from text in a structured format',\n\t\tcodex: {\n\t\t\talias: ['NER', 'parse', 'parsing', 'JSON', 'data extraction', 'structured'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tdefaults: {\n\t\t\tname: 'Information Extractor',\n\t\t},\n\t\tinputs: [\n\t\t\t{ displayName: '', type: NodeConnectionTypes.Main },\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription: 'The text to extract information from',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...schemaTypeField,\n\t\t\t\tdescription: 'How to specify the schema for the desired output',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'From Attribute Descriptions',\n\t\t\t\t\t\tvalue: 'fromAttributes',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Extract specific attributes from the text based on types and descriptions',\n\t\t\t\t\t} as INodePropertyOptions,\n\t\t\t\t\t...(schemaTypeField.options as INodePropertyOptions[]),\n\t\t\t\t],\n\t\t\t\tdefault: 'fromAttributes',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonSchemaExampleField,\n\t\t\t\tdefault: `{\n\t\"state\": \"California\",\n\t\"cities\": [\"Los Angeles\", \"San Francisco\", \"San Diego\"]\n}`,\n\t\t\t},\n\t\t\t{\n\t\t\t\t...inputSchemaField,\n\t\t\t\tdefault: `{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"state\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n\t\t\"cities\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"string\"\n\t\t\t}\n\t\t}\n\t}\n}`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'The schema has to be defined in the <a target=\"_blank\" href=\"https://json-schema.org/\">JSON Schema</a> format. Look at <a target=\"_blank\" href=\"https://json-schema.org/learn/miscellaneous-examples.html\">this</a> page for examples.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tschemaType: ['manual'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Attributes',\n\t\t\t\tname: 'attributes',\n\t\t\t\tplaceholder: 'Add Attribute',\n\t\t\t\ttype: 'fixedCollection',\n\t\t\t\tdefault: {},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tschemaType: ['fromAttributes'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tmultipleValues: true,\n\t\t\t\t},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'attributes',\n\t\t\t\t\t\tdisplayName: 'Attribute List',\n\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Name',\n\t\t\t\t\t\t\t\tname: 'name',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tdescription: 'Attribute to extract',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. company_name',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Type',\n\t\t\t\t\t\t\t\tname: 'type',\n\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\tdescription: 'Data type of the attribute',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'Boolean',\n\t\t\t\t\t\t\t\t\t\tvalue: 'boolean',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'Date',\n\t\t\t\t\t\t\t\t\t\tvalue: 'date',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'Number',\n\t\t\t\t\t\t\t\t\t\tvalue: 'number',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'String',\n\t\t\t\t\t\t\t\t\t\tvalue: 'string',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdefault: 'string',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Description',\n\t\t\t\t\t\t\t\tname: 'description',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tdescription: 'Describe your attribute',\n\t\t\t\t\t\t\t\tplaceholder: 'Add description for the attribute',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Required',\n\t\t\t\t\t\t\t\tname: 'required',\n\t\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\t\t\tdescription: 'Whether attribute is required',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'System Prompt Template',\n\t\t\t\t\t\tname: 'systemPromptTemplate',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: SYSTEM_PROMPT_TEMPLATE,\n\t\t\t\t\t\tdescription: 'String to use directly as the system prompt template',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Batch Processing',\n\t\t\t\t\t\tname: 'batching',\n\t\t\t\t\t\ttype: 'collection',\n\t\t\t\t\t\tdescription: 'Batch processing options for rate limiting',\n\t\t\t\t\t\tdefault: {},\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Batch Size',\n\t\t\t\t\t\t\t\tname: 'batchSize',\n\t\t\t\t\t\t\t\tdefault: 100,\n\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'How many items to process in parallel. This is useful for rate limiting, but will impact the agents log output.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Delay Between Batches',\n\t\t\t\t\t\t\t\tname: 'delayBetweenBatches',\n\t\t\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Delay in milliseconds between batches. This is useful for rate limiting.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\t\tconst { batchSize, delayBetweenBatches } = this.getNodeParameter('options.batching', 0, {\n\t\t\tbatchSize: 100,\n\t\t\tdelayBetweenBatches: 0,\n\t\t}) as {\n\t\t\tbatchSize: number;\n\t\t\tdelayBetweenBatches: number;\n\t\t};\n\n\t\tconst llm = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t0,\n\t\t)) as BaseLanguageModel;\n\n\t\tconst schemaType = this.getNodeParameter('schemaType', 0, '') as\n\t\t\t| 'fromAttributes'\n\t\t\t| 'fromJson'\n\t\t\t| 'manual';\n\n\t\tlet parser: OutputFixingParser<object>;\n\n\t\tif (schemaType === 'fromAttributes') {\n\t\t\tconst attributes = this.getNodeParameter(\n\t\t\t\t'attributes.attributes',\n\t\t\t\t0,\n\t\t\t\t[],\n\t\t\t) as AttributeDefinition[];\n\n\t\t\tif (attributes.length === 0) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'At least one attribute must be specified');\n\t\t\t}\n\n\t\t\tparser = OutputFixingParser.fromLLM(\n\t\t\t\tllm,\n\t\t\t\tStructuredOutputParser.fromZodSchema(makeZodSchemaFromAttributes(attributes)),\n\t\t\t);\n\t\t} else {\n\t\t\tlet jsonSchema: JSONSchema7;\n\n\t\t\tif (schemaType === 'fromJson') {\n\t\t\t\tconst jsonExample = this.getNodeParameter('jsonSchemaExample', 0, '') as string;\n\t\t\t\tjsonSchema = generateSchema(jsonExample);\n\t\t\t} else {\n\t\t\t\tconst inputSchema = this.getNodeParameter('inputSchema', 0, '') as string;\n\t\t\t\tjsonSchema = jsonParse<JSONSchema7>(inputSchema);\n\t\t\t}\n\n\t\t\tconst zodSchema = convertJsonSchemaToZod<z.ZodSchema<object>>(jsonSchema);\n\n\t\t\tparser = OutputFixingParser.fromLLM(llm, StructuredOutputParser.fromZodSchema(zodSchema));\n\t\t}\n\n\t\tconst resultData: INodeExecutionData[] = [];\n\n\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\tconst batch = items.slice(i, i + batchSize);\n\n\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\tconst itemIndex = i + batchItemIndex;\n\n\t\t\t\tconst input = this.getNodeParameter('text', itemIndex) as string;\n\t\t\t\tconst inputPrompt = new HumanMessage(input);\n\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\t\tsystemPromptTemplate?: string;\n\t\t\t\t};\n\n\t\t\t\tconst systemPromptTemplate = SystemMessagePromptTemplate.fromTemplate(\n\t\t\t\t\t`${options.systemPromptTemplate ?? SYSTEM_PROMPT_TEMPLATE}\n\t{format_instructions}`,\n\t\t\t\t);\n\n\t\t\t\tconst messages = [\n\t\t\t\t\tawait systemPromptTemplate.format({\n\t\t\t\t\t\tformat_instructions: parser.getFormatInstructions(),\n\t\t\t\t\t}),\n\t\t\t\t\tinputPrompt,\n\t\t\t\t];\n\t\t\t\tconst prompt = ChatPromptTemplate.fromMessages(messages);\n\t\t\t\tconst chain = prompt.pipe(llm).pipe(parser).withConfig(getTracingConfig(this));\n\n\t\t\t\treturn await chain.invoke(messages);\n\t\t\t});\n\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\tconst error = response.reason as Error;\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\tresultData.push({\n\t\t\t\t\t\t\tjson: { error: response.reason as string },\n\t\t\t\t\t\t\tpairedItem: { item: i + index },\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error.message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst output = response.value;\n\t\t\t\tresultData.push({ json: { output } });\n\t\t\t});\n\n\t\t\t// Add delay between batches if not the last batch\n\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t}\n\t\t}\n\n\t\treturn [resultData];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAA6B;AAC7B,qBAAgE;AAEhE,4BAA2D;AAC3D,0BAA0E;AAU1E,0BAA0E;AAC1E,2BAAuD;AACvD,qBAAiC;AAEjC,qBAA4C;AAG5C,MAAM,yBAAyB;AAAA;AAAA;AAIxB,MAAM,qBAA0C;AAAA,EAAhD;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,OAAO;AAAA,QACN,OAAO,CAAC,OAAO,SAAS,WAAW,QAAQ,mBAAmB,YAAY;AAAA,QAC1E,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,UAAU,YAAY;AAAA,QAC5B;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,QAAQ;AAAA,QACP,EAAE,aAAa,IAAI,MAAM,wCAAoB,KAAK;AAAA,QAClD;AAAA,UACC,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,MAAM,wCAAoB;AAAA,UAC1B,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,YAAY;AAAA,QACX;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,UACb,aAAa;AAAA,YACZ,MAAM;AAAA,UACP;AAAA,QACD;AAAA,QACA;AAAA,UACC,GAAG;AAAA,UACH,aAAa;AAAA,UACb,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aACC;AAAA,YACF;AAAA,YACA,GAAI,oCAAgB;AAAA,UACrB;AAAA,UACA,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,GAAG;AAAA,UACH,SAAS;AAAA;AAAA;AAAA;AAAA,QAIV;AAAA,QACA;AAAA,UACC,GAAG;AAAA,UACH,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAcV;AAAA,QACA;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,QAAQ;AAAA,YACtB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,gBAAgB;AAAA,YAC9B;AAAA,UACD;AAAA,UACA,aAAa;AAAA,YACZ,gBAAgB;AAAA,UACjB;AAAA,UACA,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,aAAa;AAAA,cACb,QAAQ;AAAA,gBACP;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,UAAU;AAAA,gBACX;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,UAAU;AAAA,kBACV,SAAS;AAAA,oBACR;AAAA,sBACC,MAAM;AAAA,sBACN,OAAO;AAAA,oBACR;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,OAAO;AAAA,oBACR;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,OAAO;AAAA,oBACR;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,OAAO;AAAA,oBACR;AAAA,kBACD;AAAA,kBACA,SAAS;AAAA,gBACV;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb,UAAU;AAAA,gBACX;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aAAa;AAAA,kBACb,UAAU;AAAA,gBACX;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,aAAa;AAAA,UACb,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,aAAa;AAAA,gBACZ,MAAM;AAAA,cACP;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,SAAS,CAAC;AAAA,cACV,SAAS;AAAA,gBACR;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,aACC;AAAA,gBACF;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,aACC;AAAA,gBACF;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,UAAkE;AACvE,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,EAAE,WAAW,oBAAoB,IAAI,KAAK,iBAAiB,oBAAoB,GAAG;AAAA,MACvF,WAAW;AAAA,MACX,qBAAqB;AAAA,IACtB,CAAC;AAKD,UAAM,MAAO,MAAM,KAAK;AAAA,MACvB,wCAAoB;AAAA,MACpB;AAAA,IACD;AAEA,UAAM,aAAa,KAAK,iBAAiB,cAAc,GAAG,EAAE;AAK5D,QAAI;AAEJ,QAAI,eAAe,kBAAkB;AACpC,YAAM,aAAa,KAAK;AAAA,QACvB;AAAA,QACA;AAAA,QACA,CAAC;AAAA,MACF;AAEA,UAAI,WAAW,WAAW,GAAG;AAC5B,cAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,0CAA0C;AAAA,MACxF;AAEA,eAAS,yCAAmB;AAAA,QAC3B;AAAA,QACA,6CAAuB,kBAAc,4CAA4B,UAAU,CAAC;AAAA,MAC7E;AAAA,IACD,OAAO;AACN,UAAI;AAEJ,UAAI,eAAe,YAAY;AAC9B,cAAM,cAAc,KAAK,iBAAiB,qBAAqB,GAAG,EAAE;AACpE,yBAAa,qCAAe,WAAW;AAAA,MACxC,OAAO;AACN,cAAM,cAAc,KAAK,iBAAiB,eAAe,GAAG,EAAE;AAC9D,yBAAa,+BAAuB,WAAW;AAAA,MAChD;AAEA,YAAM,gBAAY,6CAA4C,UAAU;AAExE,eAAS,yCAAmB,QAAQ,KAAK,6CAAuB,cAAc,SAAS,CAAC;AAAA,IACzF;AAEA,UAAM,aAAmC,CAAC;AAE1C,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,WAAW;AACjD,YAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,SAAS;AAE1C,YAAM,gBAAgB,MAAM,IAAI,OAAO,OAAO,mBAAmB;AAChE,cAAM,YAAY,IAAI;AAEtB,cAAM,QAAQ,KAAK,iBAAiB,QAAQ,SAAS;AACrD,cAAM,cAAc,IAAI,6BAAa,KAAK;AAE1C,cAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAI9D,cAAM,uBAAuB,2CAA4B;AAAA,UACxD,GAAG,QAAQ,wBAAwB,sBAAsB;AAAA;AAAA,QAE1D;AAEA,cAAM,WAAW;AAAA,UAChB,MAAM,qBAAqB,OAAO;AAAA,YACjC,qBAAqB,OAAO,sBAAsB;AAAA,UACnD,CAAC;AAAA,UACD;AAAA,QACD;AACA,cAAM,SAAS,kCAAmB,aAAa,QAAQ;AACvD,cAAM,QAAQ,OAAO,KAAK,GAAG,EAAE,KAAK,MAAM,EAAE,eAAW,iCAAiB,IAAI,CAAC;AAE7E,eAAO,MAAM,MAAM,OAAO,QAAQ;AAAA,MACnC,CAAC;AACD,YAAM,eAAe,MAAM,QAAQ,WAAW,aAAa;AAE3D,mBAAa,QAAQ,CAAC,UAAU,UAAU;AACzC,YAAI,SAAS,WAAW,YAAY;AACnC,gBAAM,QAAQ,SAAS;AACvB,cAAI,KAAK,eAAe,GAAG;AAC1B,uBAAW,KAAK;AAAA,cACf,MAAM,EAAE,OAAO,SAAS,OAAiB;AAAA,cACzC,YAAY,EAAE,MAAM,IAAI,MAAM;AAAA,YAC/B,CAAC;AACD;AAAA,UACD,OAAO;AACN,kBAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,MAAM,OAAO;AAAA,UAC3D;AAAA,QACD;AACA,cAAM,SAAS,SAAS;AACxB,mBAAW,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,MACrC,CAAC;AAGD,UAAI,IAAI,YAAY,MAAM,UAAU,sBAAsB,GAAG;AAC5D,kBAAM,2BAAM,mBAAmB;AAAA,MAChC;AAAA,IACD;AAEA,WAAO,CAAC,UAAU;AAAA,EACnB;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/chains/InformationExtractor/InformationExtractor.node.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport { HumanMessage } from '@langchain/core/messages';\nimport { ChatPromptTemplate, SystemMessagePromptTemplate } from '@langchain/core/prompts';\nimport type { JSONSchema7 } from 'json-schema';\nimport { OutputFixingParser, StructuredOutputParser } from 'langchain/output_parsers';\nimport { jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodePropertyOptions,\n} from 'n8n-workflow';\nimport type { z } from 'zod';\n\nimport { inputSchemaField, jsonSchemaExampleField, schemaTypeField } from '@utils/descriptions';\nimport { convertJsonSchemaToZod, generateSchema } from '@utils/schemaParsing';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { makeZodSchemaFromAttributes } from './helpers';\nimport type { AttributeDefinition } from './types';\n\nconst SYSTEM_PROMPT_TEMPLATE = `You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value.`;\n\nexport class InformationExtractor implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Information Extractor',\n\t\tname: 'informationExtractor',\n\t\ticon: 'fa:project-diagram',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'Extract information from text in a structured format',\n\t\tcodex: {\n\t\t\talias: ['NER', 'parse', 'parsing', 'JSON', 'data extraction', 'structured'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tdefaults: {\n\t\t\tname: 'Information Extractor',\n\t\t},\n\t\tinputs: [\n\t\t\t{ displayName: '', type: NodeConnectionTypes.Main },\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiLanguageModel,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tdescription: 'The text to extract information from',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...schemaTypeField,\n\t\t\t\tdescription: 'How to specify the schema for the desired output',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'From Attribute Descriptions',\n\t\t\t\t\t\tvalue: 'fromAttributes',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Extract specific attributes from the text based on types and descriptions',\n\t\t\t\t\t} as INodePropertyOptions,\n\t\t\t\t\t...(schemaTypeField.options as INodePropertyOptions[]),\n\t\t\t\t],\n\t\t\t\tdefault: 'fromAttributes',\n\t\t\t},\n\t\t\t{\n\t\t\t\t...jsonSchemaExampleField,\n\t\t\t\tdefault: `{\n\t\"state\": \"California\",\n\t\"cities\": [\"Los Angeles\", \"San Francisco\", \"San Diego\"]\n}`,\n\t\t\t},\n\t\t\t{\n\t\t\t\t...inputSchemaField,\n\t\t\t\tdefault: `{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"state\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n\t\t\"cities\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"string\"\n\t\t\t}\n\t\t}\n\t}\n}`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'The schema has to be defined in the <a target=\"_blank\" href=\"https://json-schema.org/\">JSON Schema</a> format. Look at <a target=\"_blank\" href=\"https://json-schema.org/learn/miscellaneous-examples.html\">this</a> page for examples.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tschemaType: ['manual'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Attributes',\n\t\t\t\tname: 'attributes',\n\t\t\t\tplaceholder: 'Add Attribute',\n\t\t\t\ttype: 'fixedCollection',\n\t\t\t\tdefault: {},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tschemaType: ['fromAttributes'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tmultipleValues: true,\n\t\t\t\t},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'attributes',\n\t\t\t\t\t\tdisplayName: 'Attribute List',\n\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Name',\n\t\t\t\t\t\t\t\tname: 'name',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tdescription: 'Attribute to extract',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. company_name',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Type',\n\t\t\t\t\t\t\t\tname: 'type',\n\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\tdescription: 'Data type of the attribute',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'Boolean',\n\t\t\t\t\t\t\t\t\t\tvalue: 'boolean',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'Date',\n\t\t\t\t\t\t\t\t\t\tvalue: 'date',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'Number',\n\t\t\t\t\t\t\t\t\t\tvalue: 'number',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tname: 'String',\n\t\t\t\t\t\t\t\t\t\tvalue: 'string',\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdefault: 'string',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Description',\n\t\t\t\t\t\t\t\tname: 'description',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tdescription: 'Describe your attribute',\n\t\t\t\t\t\t\t\tplaceholder: 'Add description for the attribute',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Required',\n\t\t\t\t\t\t\t\tname: 'required',\n\t\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\t\t\tdescription: 'Whether attribute is required',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'System Prompt Template',\n\t\t\t\t\t\tname: 'systemPromptTemplate',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: SYSTEM_PROMPT_TEMPLATE,\n\t\t\t\t\t\tdescription: 'String to use directly as the system prompt template',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\trows: 6,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData();\n\n\t\tconst llm = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\t0,\n\t\t)) as BaseLanguageModel;\n\n\t\tconst schemaType = this.getNodeParameter('schemaType', 0, '') as\n\t\t\t| 'fromAttributes'\n\t\t\t| 'fromJson'\n\t\t\t| 'manual';\n\n\t\tlet parser: OutputFixingParser<object>;\n\n\t\tif (schemaType === 'fromAttributes') {\n\t\t\tconst attributes = this.getNodeParameter(\n\t\t\t\t'attributes.attributes',\n\t\t\t\t0,\n\t\t\t\t[],\n\t\t\t) as AttributeDefinition[];\n\n\t\t\tif (attributes.length === 0) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), 'At least one attribute must be specified');\n\t\t\t}\n\n\t\t\tparser = OutputFixingParser.fromLLM(\n\t\t\t\tllm,\n\t\t\t\tStructuredOutputParser.fromZodSchema(makeZodSchemaFromAttributes(attributes)),\n\t\t\t);\n\t\t} else {\n\t\t\tlet jsonSchema: JSONSchema7;\n\n\t\t\tif (schemaType === 'fromJson') {\n\t\t\t\tconst jsonExample = this.getNodeParameter('jsonSchemaExample', 0, '') as string;\n\t\t\t\tjsonSchema = generateSchema(jsonExample);\n\t\t\t} else {\n\t\t\t\tconst inputSchema = this.getNodeParameter('inputSchema', 0, '') as string;\n\t\t\t\tjsonSchema = jsonParse<JSONSchema7>(inputSchema);\n\t\t\t}\n\n\t\t\tconst zodSchema = convertJsonSchemaToZod<z.ZodSchema<object>>(jsonSchema);\n\n\t\t\tparser = OutputFixingParser.fromLLM(llm, StructuredOutputParser.fromZodSchema(zodSchema));\n\t\t}\n\n\t\tconst resultData: INodeExecutionData[] = [];\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst input = this.getNodeParameter('text', itemIndex) as string;\n\t\t\tconst inputPrompt = new HumanMessage(input);\n\n\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\tsystemPromptTemplate?: string;\n\t\t\t};\n\n\t\t\tconst systemPromptTemplate = SystemMessagePromptTemplate.fromTemplate(\n\t\t\t\t`${options.systemPromptTemplate ?? SYSTEM_PROMPT_TEMPLATE}\n{format_instructions}`,\n\t\t\t);\n\n\t\t\tconst messages = [\n\t\t\t\tawait systemPromptTemplate.format({\n\t\t\t\t\tformat_instructions: parser.getFormatInstructions(),\n\t\t\t\t}),\n\t\t\t\tinputPrompt,\n\t\t\t];\n\t\t\tconst prompt = ChatPromptTemplate.fromMessages(messages);\n\t\t\tconst chain = prompt.pipe(llm).pipe(parser).withConfig(getTracingConfig(this));\n\n\t\t\ttry {\n\t\t\t\tconst output = await chain.invoke(messages);\n\t\t\t\tresultData.push({ json: { output } });\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\tresultData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn [resultData];\n\t}\n}\n"],"mappings":"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","names":[]}
|