@n8n/n8n-nodes-langchain 1.93.0 → 1.95.0
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/credentials/AzureEntraCognitiveServicesOAuth2Api.credentials.js +4 -21
- package/dist/credentials/AzureEntraCognitiveServicesOAuth2Api.credentials.js.map +1 -1
- package/dist/nodes/agents/Agent/Agent.node.js +19 -394
- package/dist/nodes/agents/Agent/Agent.node.js.map +1 -1
- package/dist/nodes/agents/Agent/V1/AgentV1.node.js +427 -0
- package/dist/nodes/agents/Agent/V1/AgentV1.node.js.map +1 -0
- package/dist/nodes/agents/Agent/V2/AgentV2.node.js +162 -0
- package/dist/nodes/agents/Agent/V2/AgentV2.node.js.map +1 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/{description.js → V1/description.js} +2 -34
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/description.js.map +1 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js +119 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js.map +1 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js +40 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/description.js.map +1 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +139 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/{execute.js → common.js} +7 -97
- package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js.map +1 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/options.js +62 -0
- package/dist/nodes/agents/Agent/agents/ToolsAgent/options.js.map +1 -0
- package/dist/nodes/chains/ChainLLM/ChainLlm.node.js +69 -51
- package/dist/nodes/chains/ChainLLM/ChainLlm.node.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js +8 -0
- package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/methods/config.js +5 -0
- package/dist/nodes/chains/ChainLLM/methods/config.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/methods/processItem.js +66 -0
- package/dist/nodes/chains/ChainLLM/methods/processItem.js.map +1 -0
- package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js +71 -95
- package/dist/nodes/chains/ChainRetrievalQA/ChainRetrievalQa.node.js.map +1 -1
- package/dist/nodes/chains/ChainRetrievalQA/constants.js +49 -0
- package/dist/nodes/chains/ChainRetrievalQA/constants.js.map +1 -0
- package/dist/nodes/chains/ChainRetrievalQA/processItem.js +91 -0
- package/dist/nodes/chains/ChainRetrievalQA/processItem.js.map +1 -0
- package/dist/nodes/chains/ChainSummarization/ChainSummarization.node.js +3 -2
- package/dist/nodes/chains/ChainSummarization/ChainSummarization.node.js.map +1 -1
- package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js +55 -78
- package/dist/nodes/chains/ChainSummarization/V2/ChainSummarizationV2.node.js.map +1 -1
- package/dist/nodes/chains/ChainSummarization/V2/processItem.js +95 -0
- package/dist/nodes/chains/ChainSummarization/V2/processItem.js.map +1 -0
- package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js +56 -33
- package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js.map +1 -1
- package/dist/nodes/chains/InformationExtractor/constants.js +31 -0
- package/dist/nodes/chains/InformationExtractor/constants.js.map +1 -0
- package/dist/nodes/chains/InformationExtractor/processItem.js +56 -0
- package/dist/nodes/chains/InformationExtractor/processItem.js.map +1 -0
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js +198 -71
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js.map +1 -1
- package/dist/nodes/chains/TextClassifier/TextClassifier.node.js +83 -54
- package/dist/nodes/chains/TextClassifier/TextClassifier.node.js.map +1 -1
- package/dist/nodes/chains/TextClassifier/constants.js +29 -0
- package/dist/nodes/chains/TextClassifier/constants.js.map +1 -0
- package/dist/nodes/chains/TextClassifier/processItem.js +65 -0
- package/dist/nodes/chains/TextClassifier/processItem.js.map +1 -0
- package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js +7 -3
- package/dist/nodes/llms/LMChatAnthropic/LmChatAnthropic.node.js.map +1 -1
- package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js +4 -1
- package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js.map +1 -1
- package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js +6 -1
- package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js.map +1 -1
- package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js +4 -1
- package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js.map +1 -1
- package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js +4 -0
- package/dist/nodes/llms/LmChatAwsBedrock/LmChatAwsBedrock.node.js.map +1 -1
- package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js +4 -0
- package/dist/nodes/llms/LmChatAzureOpenAi/LmChatAzureOpenAi.node.js.map +1 -1
- package/dist/nodes/llms/LmChatAzureOpenAi/credentials/N8nOAuth2TokenCredential.js +16 -2
- package/dist/nodes/llms/LmChatAzureOpenAi/credentials/N8nOAuth2TokenCredential.js.map +1 -1
- package/dist/nodes/llms/LmChatDeepSeek/LmChatDeepSeek.node.js +3 -1
- package/dist/nodes/llms/LmChatDeepSeek/LmChatDeepSeek.node.js.map +1 -1
- package/dist/nodes/llms/LmChatGroq/LmChatGroq.node.js +2 -0
- package/dist/nodes/llms/LmChatGroq/LmChatGroq.node.js.map +1 -1
- package/dist/nodes/llms/LmChatOpenRouter/LmChatOpenRouter.node.js +3 -1
- package/dist/nodes/llms/LmChatOpenRouter/LmChatOpenRouter.node.js.map +1 -1
- package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js +3 -1
- package/dist/nodes/llms/LmChatXAiGrok/LmChatXAiGrok.node.js.map +1 -1
- package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js +2 -2
- package/dist/nodes/mcp/McpTrigger/McpTrigger.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js +1 -0
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js +2 -1
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +1 -1
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
- package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js +109 -17
- package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js.map +1 -1
- package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js +3 -0
- package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js.map +1 -1
- package/dist/nodes/vector_store/shared/createVectorStoreNode/createVectorStoreNode.js +2 -1
- package/dist/nodes/vector_store/shared/createVectorStoreNode/createVectorStoreNode.js.map +1 -1
- package/dist/nodes/vector_store/shared/createVectorStoreNode/types.js.map +1 -1
- package/dist/nodes/vendors/OpenAi/actions/image/generate.operation.js +6 -1
- package/dist/nodes/vendors/OpenAi/actions/image/generate.operation.js.map +1 -1
- package/dist/types/credentials.json +1 -1
- package/dist/types/nodes.json +20 -19
- package/dist/utils/httpProxyAgent.js +33 -0
- package/dist/utils/httpProxyAgent.js.map +1 -0
- package/dist/utils/sharedFields.js +29 -0
- package/dist/utils/sharedFields.js.map +1 -1
- package/package.json +7 -6
- package/dist/nodes/agents/Agent/agents/ToolsAgent/description.js.map +0 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/execute.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/chains/ChainSummarization/V2/processItem.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 { RecursiveCharacterTextSplitter, type TextSplitter } from '@langchain/textsplitters';\nimport { loadSummarizationChain } from 'langchain/chains';\nimport { type IExecuteFunctions, type INodeExecutionData, NodeConnectionTypes } from 'n8n-workflow';\n\nimport { N8nBinaryLoader } from '@utils/N8nBinaryLoader';\nimport { N8nJsonLoader } from '@utils/N8nJsonLoader';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { getChainPromptsArgs } from '../helpers';\n\nexport async function processItem(\n\tctx: IExecuteFunctions,\n\titemIndex: number,\n\titem: INodeExecutionData,\n\toperationMode: string,\n\tchunkingMode: 'simple' | 'advanced' | 'none',\n): Promise<ChainValues | undefined> {\n\tconst model = (await ctx.getInputConnectionData(\n\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t0,\n\t)) as BaseLanguageModel;\n\n\tconst summarizationMethodAndPrompts = ctx.getNodeParameter(\n\t\t'options.summarizationMethodAndPrompts.values',\n\t\titemIndex,\n\t\t{},\n\t) as {\n\t\tprompt?: string;\n\t\trefineQuestionPrompt?: string;\n\t\trefinePrompt?: string;\n\t\tsummarizationMethod: 'map_reduce' | 'stuff' | 'refine';\n\t\tcombineMapPrompt?: string;\n\t};\n\n\tconst chainArgs = getChainPromptsArgs(\n\t\tsummarizationMethodAndPrompts.summarizationMethod ?? 'map_reduce',\n\t\tsummarizationMethodAndPrompts,\n\t);\n\n\tconst chain = loadSummarizationChain(model, chainArgs);\n\n\tlet processedDocuments: Document[];\n\n\t// Use dedicated document loader input to load documents\n\tif (operationMode === 'documentLoader') {\n\t\tconst documentInput = (await ctx.getInputConnectionData(NodeConnectionTypes.AiDocument, 0)) as\n\t\t\t| N8nJsonLoader\n\t\t\t| Array<Document<Record<string, unknown>>>;\n\n\t\tconst isN8nLoader =\n\t\t\tdocumentInput instanceof N8nJsonLoader || documentInput instanceof N8nBinaryLoader;\n\n\t\tprocessedDocuments = isN8nLoader\n\t\t\t? await documentInput.processItem(item, itemIndex)\n\t\t\t: documentInput;\n\n\t\treturn await chain.withConfig(getTracingConfig(ctx)).invoke({\n\t\t\tinput_documents: processedDocuments,\n\t\t});\n\t} else if (['nodeInputJson', 'nodeInputBinary'].includes(operationMode)) {\n\t\t// Take the input and use binary or json loader\n\t\tlet textSplitter: TextSplitter | undefined;\n\n\t\tswitch (chunkingMode) {\n\t\t\t// In simple mode we use recursive character splitter with default settings\n\t\t\tcase 'simple':\n\t\t\t\tconst chunkSize = ctx.getNodeParameter('chunkSize', itemIndex, 1000) as number;\n\t\t\t\tconst chunkOverlap = ctx.getNodeParameter('chunkOverlap', itemIndex, 200) as number;\n\n\t\t\t\ttextSplitter = new RecursiveCharacterTextSplitter({ chunkOverlap, chunkSize });\n\t\t\t\tbreak;\n\n\t\t\t// In advanced mode user can connect text splitter node so we just retrieve it\n\t\t\tcase 'advanced':\n\t\t\t\ttextSplitter = (await ctx.getInputConnectionData(NodeConnectionTypes.AiTextSplitter, 0)) as\n\t\t\t\t\t| TextSplitter\n\t\t\t\t\t| undefined;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\tlet processor: N8nJsonLoader | N8nBinaryLoader;\n\t\tif (operationMode === 'nodeInputBinary') {\n\t\t\tconst binaryDataKey = ctx.getNodeParameter(\n\t\t\t\t'options.binaryDataKey',\n\t\t\t\titemIndex,\n\t\t\t\t'data',\n\t\t\t) as string;\n\t\t\tprocessor = new N8nBinaryLoader(ctx, 'options.', binaryDataKey, textSplitter);\n\t\t} else {\n\t\t\tprocessor = new N8nJsonLoader(ctx, 'options.', textSplitter);\n\t\t}\n\n\t\tconst processedItem = await processor.processItem(item, itemIndex);\n\t\treturn await chain.invoke(\n\t\t\t{\n\t\t\t\tinput_documents: processedItem,\n\t\t\t},\n\t\t\t{ signal: ctx.getExecutionCancelSignal() },\n\t\t);\n\t}\n\treturn undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,2BAAkE;AAClE,oBAAuC;AACvC,0BAAqF;AAErF,6BAAgC;AAChC,2BAA8B;AAC9B,qBAAiC;AAEjC,qBAAoC;AAEpC,eAAsB,YACrB,KACA,WACA,MACA,eACA,cACmC;AACnC,QAAM,QAAS,MAAM,IAAI;AAAA,IACxB,wCAAoB;AAAA,IACpB;AAAA,EACD;AAEA,QAAM,gCAAgC,IAAI;AAAA,IACzC;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACF;AAQA,QAAM,gBAAY;AAAA,IACjB,8BAA8B,uBAAuB;AAAA,IACrD;AAAA,EACD;AAEA,QAAM,YAAQ,sCAAuB,OAAO,SAAS;AAErD,MAAI;AAGJ,MAAI,kBAAkB,kBAAkB;AACvC,UAAM,gBAAiB,MAAM,IAAI,uBAAuB,wCAAoB,YAAY,CAAC;AAIzF,UAAM,cACL,yBAAyB,sCAAiB,yBAAyB;AAEpE,yBAAqB,cAClB,MAAM,cAAc,YAAY,MAAM,SAAS,IAC/C;AAEH,WAAO,MAAM,MAAM,eAAW,iCAAiB,GAAG,CAAC,EAAE,OAAO;AAAA,MAC3D,iBAAiB;AAAA,IAClB,CAAC;AAAA,EACF,WAAW,CAAC,iBAAiB,iBAAiB,EAAE,SAAS,aAAa,GAAG;AAExE,QAAI;AAEJ,YAAQ,cAAc;AAAA;AAAA,MAErB,KAAK;AACJ,cAAM,YAAY,IAAI,iBAAiB,aAAa,WAAW,GAAI;AACnE,cAAM,eAAe,IAAI,iBAAiB,gBAAgB,WAAW,GAAG;AAExE,uBAAe,IAAI,oDAA+B,EAAE,cAAc,UAAU,CAAC;AAC7E;AAAA;AAAA,MAGD,KAAK;AACJ,uBAAgB,MAAM,IAAI,uBAAuB,wCAAoB,gBAAgB,CAAC;AAGtF;AAAA,MACD;AACC;AAAA,IACF;AAEA,QAAI;AACJ,QAAI,kBAAkB,mBAAmB;AACxC,YAAM,gBAAgB,IAAI;AAAA,QACzB;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,kBAAY,IAAI,uCAAgB,KAAK,YAAY,eAAe,YAAY;AAAA,IAC7E,OAAO;AACN,kBAAY,IAAI,mCAAc,KAAK,YAAY,YAAY;AAAA,IAC5D;AAEA,UAAM,gBAAgB,MAAM,UAAU,YAAY,MAAM,SAAS;AACjE,WAAO,MAAM,MAAM;AAAA,MAClB;AAAA,QACC,iBAAiB;AAAA,MAClB;AAAA,MACA,EAAE,QAAQ,IAAI,yBAAyB,EAAE;AAAA,IAC1C;AAAA,EACD;AACA,SAAO;AACR;","names":[]}
|
|
@@ -21,17 +21,14 @@ __export(InformationExtractor_node_exports, {
|
|
|
21
21
|
InformationExtractor: () => InformationExtractor
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(InformationExtractor_node_exports);
|
|
24
|
-
var import_messages = require("@langchain/core/messages");
|
|
25
|
-
var import_prompts = require("@langchain/core/prompts");
|
|
26
24
|
var import_output_parsers = require("langchain/output_parsers");
|
|
27
25
|
var import_n8n_workflow = require("n8n-workflow");
|
|
28
26
|
var import_descriptions = require("../../../utils/descriptions");
|
|
29
27
|
var import_schemaParsing = require("../../../utils/schemaParsing");
|
|
30
|
-
var
|
|
28
|
+
var import_sharedFields = require("../../../utils/sharedFields");
|
|
29
|
+
var import_constants = require("./constants");
|
|
31
30
|
var import_helpers = require("./helpers");
|
|
32
|
-
|
|
33
|
-
Only extract relevant information from the text.
|
|
34
|
-
If you do not know the value of an attribute asked to extract, you may omit the attribute's value.`;
|
|
31
|
+
var import_processItem = require("./processItem");
|
|
35
32
|
class InformationExtractor {
|
|
36
33
|
constructor() {
|
|
37
34
|
this.description = {
|
|
@@ -40,7 +37,7 @@ class InformationExtractor {
|
|
|
40
37
|
icon: "fa:project-diagram",
|
|
41
38
|
iconColor: "black",
|
|
42
39
|
group: ["transform"],
|
|
43
|
-
version: 1,
|
|
40
|
+
version: [1, 1.1],
|
|
44
41
|
description: "Extract information from text in a structured format",
|
|
45
42
|
codex: {
|
|
46
43
|
alias: ["NER", "parse", "parsing", "JSON", "data extraction", "structured"],
|
|
@@ -214,12 +211,17 @@ class InformationExtractor {
|
|
|
214
211
|
displayName: "System Prompt Template",
|
|
215
212
|
name: "systemPromptTemplate",
|
|
216
213
|
type: "string",
|
|
217
|
-
default: SYSTEM_PROMPT_TEMPLATE,
|
|
214
|
+
default: import_constants.SYSTEM_PROMPT_TEMPLATE,
|
|
218
215
|
description: "String to use directly as the system prompt template",
|
|
219
216
|
typeOptions: {
|
|
220
217
|
rows: 6
|
|
221
218
|
}
|
|
222
|
-
}
|
|
219
|
+
},
|
|
220
|
+
(0, import_sharedFields.getBatchingOptionFields)({
|
|
221
|
+
show: {
|
|
222
|
+
"@version": [{ _cnd: { gte: 1.1 } }]
|
|
223
|
+
}
|
|
224
|
+
})
|
|
223
225
|
]
|
|
224
226
|
}
|
|
225
227
|
]
|
|
@@ -259,31 +261,52 @@ class InformationExtractor {
|
|
|
259
261
|
parser = import_output_parsers.OutputFixingParser.fromLLM(llm, import_output_parsers.StructuredOutputParser.fromZodSchema(zodSchema));
|
|
260
262
|
}
|
|
261
263
|
const resultData = [];
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
{
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
264
|
+
const batchSize = this.getNodeParameter("options.batching.batchSize", 0, 5);
|
|
265
|
+
const delayBetweenBatches = this.getNodeParameter(
|
|
266
|
+
"options.batching.delayBetweenBatches",
|
|
267
|
+
0,
|
|
268
|
+
0
|
|
269
|
+
);
|
|
270
|
+
if (this.getNode().typeVersion >= 1.1 && batchSize >= 1) {
|
|
271
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
272
|
+
const batch = items.slice(i, i + batchSize);
|
|
273
|
+
const batchPromises = batch.map(async (_item, batchItemIndex) => {
|
|
274
|
+
const itemIndex = i + batchItemIndex;
|
|
275
|
+
return await (0, import_processItem.processItem)(this, itemIndex, llm, parser);
|
|
276
|
+
});
|
|
277
|
+
const batchResults = await Promise.allSettled(batchPromises);
|
|
278
|
+
batchResults.forEach((response, index) => {
|
|
279
|
+
if (response.status === "rejected") {
|
|
280
|
+
const error = response.reason;
|
|
281
|
+
if (this.continueOnFail()) {
|
|
282
|
+
resultData.push({
|
|
283
|
+
json: { error: error.message },
|
|
284
|
+
pairedItem: { item: i + index }
|
|
285
|
+
});
|
|
286
|
+
return;
|
|
287
|
+
} else {
|
|
288
|
+
throw new import_n8n_workflow.NodeOperationError(this.getNode(), error.message);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const output = response.value;
|
|
292
|
+
resultData.push({ json: { output } });
|
|
293
|
+
});
|
|
294
|
+
if (i + batchSize < items.length && delayBetweenBatches > 0) {
|
|
295
|
+
await (0, import_n8n_workflow.sleep)(delayBetweenBatches);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
} else {
|
|
299
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
300
|
+
try {
|
|
301
|
+
const output = await (0, import_processItem.processItem)(this, itemIndex, llm, parser);
|
|
302
|
+
resultData.push({ json: { output } });
|
|
303
|
+
} catch (error) {
|
|
304
|
+
if (this.continueOnFail()) {
|
|
305
|
+
resultData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
throw error;
|
|
285
309
|
}
|
|
286
|
-
throw error;
|
|
287
310
|
}
|
|
288
311
|
}
|
|
289
312
|
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 } 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":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/chains/InformationExtractor/InformationExtractor.node.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\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 { getBatchingOptionFields } from '@utils/sharedFields';\n\nimport { SYSTEM_PROMPT_TEMPLATE } from './constants';\nimport { makeZodSchemaFromAttributes } from './helpers';\nimport { processItem } from './processItem';\nimport type { AttributeDefinition } from './types';\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, 1.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\tgetBatchingOptionFields({\n\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.1 } }],\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\tconst batchSize = this.getNodeParameter('options.batching.batchSize', 0, 5) as number;\n\t\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t\t'options.batching.delayBetweenBatches',\n\t\t\t0,\n\t\t\t0,\n\t\t) as number;\n\t\tif (this.getNode().typeVersion >= 1.1 && batchSize >= 1) {\n\t\t\t// Batch processing\n\t\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\t\tconst itemIndex = i + batchItemIndex;\n\t\t\t\t\treturn await processItem(this, itemIndex, llm, parser);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((response, index) => {\n\t\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\t\tconst error = response.reason as Error;\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\tresultData.push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: i + index },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error.message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst output = response.value;\n\t\t\t\t\tresultData.push({ json: { output } });\n\t\t\t\t});\n\n\t\t\t\t// Add delay between batches if not the last batch\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Sequential processing\n\t\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\t\ttry {\n\t\t\t\t\tconst output = await processItem(this, itemIndex, llm, parser);\n\t\t\t\t\tresultData.push({ json: { output } });\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\tresultData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn [resultData];\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var constants_exports = {};
|
|
20
|
+
__export(constants_exports, {
|
|
21
|
+
SYSTEM_PROMPT_TEMPLATE: () => SYSTEM_PROMPT_TEMPLATE
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(constants_exports);
|
|
24
|
+
const SYSTEM_PROMPT_TEMPLATE = `You are an expert extraction algorithm.
|
|
25
|
+
Only extract relevant information from the text.
|
|
26
|
+
If you do not know the value of an attribute asked to extract, you may omit the attribute's value.`;
|
|
27
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
+
0 && (module.exports = {
|
|
29
|
+
SYSTEM_PROMPT_TEMPLATE
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/chains/InformationExtractor/constants.ts"],"sourcesContent":["export const 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"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,yBAAyB;AAAA;AAAA;","names":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var processItem_exports = {};
|
|
20
|
+
__export(processItem_exports, {
|
|
21
|
+
processItem: () => processItem
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(processItem_exports);
|
|
24
|
+
var import_messages = require("@langchain/core/messages");
|
|
25
|
+
var import_prompts = require("@langchain/core/prompts");
|
|
26
|
+
var import_n8n_workflow = require("n8n-workflow");
|
|
27
|
+
var import_tracing = require("../../../utils/tracing");
|
|
28
|
+
var import_constants = require("./constants");
|
|
29
|
+
async function processItem(ctx, itemIndex, llm, parser) {
|
|
30
|
+
const input = ctx.getNodeParameter("text", itemIndex);
|
|
31
|
+
if (!input?.trim()) {
|
|
32
|
+
throw new import_n8n_workflow.NodeOperationError(ctx.getNode(), `Text for item ${itemIndex} is not defined`, {
|
|
33
|
+
itemIndex
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const inputPrompt = new import_messages.HumanMessage(input);
|
|
37
|
+
const options = ctx.getNodeParameter("options", itemIndex, {});
|
|
38
|
+
const systemPromptTemplate = import_prompts.SystemMessagePromptTemplate.fromTemplate(
|
|
39
|
+
`${options.systemPromptTemplate ?? import_constants.SYSTEM_PROMPT_TEMPLATE}
|
|
40
|
+
{format_instructions}`
|
|
41
|
+
);
|
|
42
|
+
const messages = [
|
|
43
|
+
await systemPromptTemplate.format({
|
|
44
|
+
format_instructions: parser.getFormatInstructions()
|
|
45
|
+
}),
|
|
46
|
+
inputPrompt
|
|
47
|
+
];
|
|
48
|
+
const prompt = import_prompts.ChatPromptTemplate.fromMessages(messages);
|
|
49
|
+
const chain = prompt.pipe(llm).pipe(parser).withConfig((0, import_tracing.getTracingConfig)(ctx));
|
|
50
|
+
return await chain.invoke(messages);
|
|
51
|
+
}
|
|
52
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
53
|
+
0 && (module.exports = {
|
|
54
|
+
processItem
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=processItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/chains/InformationExtractor/processItem.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 { OutputFixingParser } from 'langchain/output_parsers';\nimport { NodeOperationError, type IExecuteFunctions } from 'n8n-workflow';\n\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { SYSTEM_PROMPT_TEMPLATE } from './constants';\n\nexport async function processItem(\n\tctx: IExecuteFunctions,\n\titemIndex: number,\n\tllm: BaseLanguageModel,\n\tparser: OutputFixingParser<object>,\n) {\n\tconst input = ctx.getNodeParameter('text', itemIndex) as string;\n\tif (!input?.trim()) {\n\t\tthrow new NodeOperationError(ctx.getNode(), `Text for item ${itemIndex} is not defined`, {\n\t\t\titemIndex,\n\t\t});\n\t}\n\tconst inputPrompt = new HumanMessage(input);\n\n\tconst options = ctx.getNodeParameter('options', itemIndex, {}) as {\n\t\tsystemPromptTemplate?: string;\n\t};\n\n\tconst systemPromptTemplate = SystemMessagePromptTemplate.fromTemplate(\n\t\t`${options.systemPromptTemplate ?? SYSTEM_PROMPT_TEMPLATE}\n{format_instructions}`,\n\t);\n\n\tconst messages = [\n\t\tawait systemPromptTemplate.format({\n\t\t\tformat_instructions: parser.getFormatInstructions(),\n\t\t}),\n\t\tinputPrompt,\n\t];\n\tconst prompt = ChatPromptTemplate.fromMessages(messages);\n\tconst chain = prompt.pipe(llm).pipe(parser).withConfig(getTracingConfig(ctx));\n\n\treturn await chain.invoke(messages);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAA6B;AAC7B,qBAAgE;AAEhE,0BAA2D;AAE3D,qBAAiC;AAEjC,uBAAuC;AAEvC,eAAsB,YACrB,KACA,WACA,KACA,QACC;AACD,QAAM,QAAQ,IAAI,iBAAiB,QAAQ,SAAS;AACpD,MAAI,CAAC,OAAO,KAAK,GAAG;AACnB,UAAM,IAAI,uCAAmB,IAAI,QAAQ,GAAG,iBAAiB,SAAS,mBAAmB;AAAA,MACxF;AAAA,IACD,CAAC;AAAA,EACF;AACA,QAAM,cAAc,IAAI,6BAAa,KAAK;AAE1C,QAAM,UAAU,IAAI,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAI7D,QAAM,uBAAuB,2CAA4B;AAAA,IACxD,GAAG,QAAQ,wBAAwB,uCAAsB;AAAA;AAAA,EAE1D;AAEA,QAAM,WAAW;AAAA,IAChB,MAAM,qBAAqB,OAAO;AAAA,MACjC,qBAAqB,OAAO,sBAAsB;AAAA,IACnD,CAAC;AAAA,IACD;AAAA,EACD;AACA,QAAM,SAAS,kCAAmB,aAAa,QAAQ;AACvD,QAAM,QAAQ,OAAO,KAAK,GAAG,EAAE,KAAK,MAAM,EAAE,eAAW,iCAAiB,GAAG,CAAC;AAE5E,SAAO,MAAM,MAAM,OAAO,QAAQ;AACnC;","names":[]}
|
|
@@ -26,6 +26,7 @@ var import_prompts = require("@langchain/core/prompts");
|
|
|
26
26
|
var import_output_parsers = require("langchain/output_parsers");
|
|
27
27
|
var import_n8n_workflow = require("n8n-workflow");
|
|
28
28
|
var import_zod = require("zod");
|
|
29
|
+
var import_sharedFields = require("../../../utils/sharedFields");
|
|
29
30
|
var import_tracing = require("../../../utils/tracing");
|
|
30
31
|
const DEFAULT_SYSTEM_PROMPT_TEMPLATE = "You are highly intelligent and accurate sentiment analyzer. Analyze the sentiment of the provided text. Categorize it into one of the following: {categories}. Use the provided formatting instructions. Only output the JSON.";
|
|
31
32
|
const DEFAULT_CATEGORIES = "Positive, Neutral, Negative";
|
|
@@ -44,7 +45,7 @@ class SentimentAnalysis {
|
|
|
44
45
|
icon: "fa:balance-scale-left",
|
|
45
46
|
iconColor: "black",
|
|
46
47
|
group: ["transform"],
|
|
47
|
-
version: 1,
|
|
48
|
+
version: [1, 1.1],
|
|
48
49
|
description: "Analyze the sentiment of your text",
|
|
49
50
|
codex: {
|
|
50
51
|
categories: ["AI"],
|
|
@@ -136,7 +137,12 @@ class SentimentAnalysis {
|
|
|
136
137
|
type: "boolean",
|
|
137
138
|
default: true,
|
|
138
139
|
description: "Whether to enable auto-fixing (may trigger an additional LLM call if output is broken)"
|
|
139
|
-
}
|
|
140
|
+
},
|
|
141
|
+
(0, import_sharedFields.getBatchingOptionFields)({
|
|
142
|
+
show: {
|
|
143
|
+
"@version": [{ _cnd: { gte: 1.1 } }]
|
|
144
|
+
}
|
|
145
|
+
})
|
|
140
146
|
]
|
|
141
147
|
}
|
|
142
148
|
]
|
|
@@ -149,84 +155,205 @@ class SentimentAnalysis {
|
|
|
149
155
|
0
|
|
150
156
|
);
|
|
151
157
|
const returnData = [];
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
const options = this.getNodeParameter("options", i, {});
|
|
169
|
-
const schema = import_zod.z.object({
|
|
170
|
-
sentiment: import_zod.z.enum(categories),
|
|
171
|
-
strength: import_zod.z.number().min(0).max(1).describe("Strength score for sentiment in relation to the category"),
|
|
172
|
-
confidence: import_zod.z.number().min(0).max(1)
|
|
173
|
-
});
|
|
174
|
-
const structuredParser = import_output_parsers.StructuredOutputParser.fromZodSchema(schema);
|
|
175
|
-
const parser = options.enableAutoFixing ? import_output_parsers.OutputFixingParser.fromLLM(llm, structuredParser) : structuredParser;
|
|
176
|
-
const systemPromptTemplate = import_prompts.SystemMessagePromptTemplate.fromTemplate(
|
|
177
|
-
`${options.systemPromptTemplate ?? DEFAULT_SYSTEM_PROMPT_TEMPLATE}
|
|
178
|
-
{format_instructions}`
|
|
179
|
-
);
|
|
180
|
-
const input = this.getNodeParameter("inputText", i);
|
|
181
|
-
const inputPrompt = new import_messages.HumanMessage(input);
|
|
182
|
-
const messages = [
|
|
183
|
-
await systemPromptTemplate.format({
|
|
184
|
-
categories: sentimentCategories,
|
|
185
|
-
format_instructions: parser.getFormatInstructions()
|
|
186
|
-
}),
|
|
187
|
-
inputPrompt
|
|
188
|
-
];
|
|
189
|
-
const prompt = import_prompts.ChatPromptTemplate.fromMessages(messages);
|
|
190
|
-
const chain = prompt.pipe(llm).pipe(parser).withConfig((0, import_tracing.getTracingConfig)(this));
|
|
191
|
-
try {
|
|
192
|
-
const output = await chain.invoke(messages);
|
|
193
|
-
const sentimentIndex = categories.findIndex(
|
|
194
|
-
(s) => s.toLowerCase() === output.sentiment.toLowerCase()
|
|
158
|
+
const batchSize = this.getNodeParameter("options.batching.batchSize", 0, 5);
|
|
159
|
+
const delayBetweenBatches = this.getNodeParameter(
|
|
160
|
+
"options.batching.delayBetweenBatches",
|
|
161
|
+
0,
|
|
162
|
+
0
|
|
163
|
+
);
|
|
164
|
+
if (this.getNode().typeVersion >= 1.1 && batchSize > 1) {
|
|
165
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
166
|
+
const batch = items.slice(i, i + batchSize);
|
|
167
|
+
const batchPromises = batch.map(async (_item, batchItemIndex) => {
|
|
168
|
+
const itemIndex = i + batchItemIndex;
|
|
169
|
+
const sentimentCategories = this.getNodeParameter(
|
|
170
|
+
"options.categories",
|
|
171
|
+
itemIndex,
|
|
172
|
+
DEFAULT_CATEGORIES
|
|
195
173
|
);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
174
|
+
const categories = sentimentCategories.split(",").map((cat) => cat.trim()).filter(Boolean);
|
|
175
|
+
if (categories.length === 0) {
|
|
176
|
+
return {
|
|
177
|
+
result: null,
|
|
178
|
+
itemIndex,
|
|
179
|
+
error: new import_n8n_workflow.NodeOperationError(this.getNode(), "No sentiment categories provided", {
|
|
180
|
+
itemIndex
|
|
181
|
+
})
|
|
200
182
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
183
|
+
}
|
|
184
|
+
if (returnData.length === 0) {
|
|
185
|
+
returnData.push(...Array.from({ length: categories.length }, () => []));
|
|
186
|
+
}
|
|
187
|
+
const options = this.getNodeParameter("options", itemIndex, {});
|
|
188
|
+
const schema = import_zod.z.object({
|
|
189
|
+
sentiment: import_zod.z.enum(categories),
|
|
190
|
+
strength: import_zod.z.number().min(0).max(1).describe("Strength score for sentiment in relation to the category"),
|
|
191
|
+
confidence: import_zod.z.number().min(0).max(1)
|
|
192
|
+
});
|
|
193
|
+
const structuredParser = import_output_parsers.StructuredOutputParser.fromZodSchema(schema);
|
|
194
|
+
const parser = options.enableAutoFixing ? import_output_parsers.OutputFixingParser.fromLLM(llm, structuredParser) : structuredParser;
|
|
195
|
+
const systemPromptTemplate = import_prompts.SystemMessagePromptTemplate.fromTemplate(
|
|
196
|
+
`${options.systemPromptTemplate ?? DEFAULT_SYSTEM_PROMPT_TEMPLATE}
|
|
197
|
+
{format_instructions}`
|
|
198
|
+
);
|
|
199
|
+
const input = this.getNodeParameter("inputText", itemIndex);
|
|
200
|
+
const inputPrompt = new import_messages.HumanMessage(input);
|
|
201
|
+
const messages = [
|
|
202
|
+
await systemPromptTemplate.format({
|
|
203
|
+
categories: sentimentCategories,
|
|
204
|
+
format_instructions: parser.getFormatInstructions()
|
|
205
|
+
}),
|
|
206
|
+
inputPrompt
|
|
207
|
+
];
|
|
208
|
+
const prompt = import_prompts.ChatPromptTemplate.fromMessages(messages);
|
|
209
|
+
const chain = prompt.pipe(llm).pipe(parser).withConfig((0, import_tracing.getTracingConfig)(this));
|
|
210
|
+
try {
|
|
211
|
+
const output = await chain.invoke(messages);
|
|
212
|
+
const sentimentIndex = categories.findIndex(
|
|
213
|
+
(s) => s.toLowerCase() === output.sentiment.toLowerCase()
|
|
214
|
+
);
|
|
215
|
+
if (sentimentIndex !== -1) {
|
|
216
|
+
const resultItem = { ...items[itemIndex] };
|
|
217
|
+
const sentimentAnalysis = {
|
|
218
|
+
category: output.sentiment
|
|
219
|
+
};
|
|
220
|
+
if (options.includeDetailedResults) {
|
|
221
|
+
sentimentAnalysis.strength = output.strength;
|
|
222
|
+
sentimentAnalysis.confidence = output.confidence;
|
|
223
|
+
}
|
|
224
|
+
resultItem.json = {
|
|
225
|
+
...resultItem.json,
|
|
226
|
+
sentimentAnalysis
|
|
227
|
+
};
|
|
228
|
+
return {
|
|
229
|
+
result: {
|
|
230
|
+
resultItem,
|
|
231
|
+
sentimentIndex
|
|
232
|
+
},
|
|
233
|
+
itemIndex
|
|
234
|
+
};
|
|
204
235
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
236
|
+
return {
|
|
237
|
+
result: {},
|
|
238
|
+
itemIndex
|
|
239
|
+
};
|
|
240
|
+
} catch (error) {
|
|
241
|
+
return {
|
|
242
|
+
result: null,
|
|
243
|
+
itemIndex,
|
|
244
|
+
error: new import_n8n_workflow.NodeOperationError(
|
|
245
|
+
this.getNode(),
|
|
246
|
+
"Error during parsing of LLM output, please check your LLM model and configuration",
|
|
247
|
+
{
|
|
248
|
+
itemIndex
|
|
249
|
+
}
|
|
250
|
+
)
|
|
208
251
|
};
|
|
209
|
-
returnData[sentimentIndex].push(resultItem);
|
|
210
252
|
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
{
|
|
216
|
-
|
|
253
|
+
});
|
|
254
|
+
const batchResults = await Promise.all(batchPromises);
|
|
255
|
+
batchResults.forEach(({ result, itemIndex, error }) => {
|
|
256
|
+
if (error) {
|
|
257
|
+
if (this.continueOnFail()) {
|
|
258
|
+
const executionErrorData = this.helpers.constructExecutionMetaData(
|
|
259
|
+
this.helpers.returnJsonArray({ error: error.message }),
|
|
260
|
+
{ itemData: { item: itemIndex } }
|
|
261
|
+
);
|
|
262
|
+
returnData[0].push(...executionErrorData);
|
|
263
|
+
return;
|
|
264
|
+
} else {
|
|
265
|
+
throw error;
|
|
217
266
|
}
|
|
218
|
-
)
|
|
267
|
+
} else if (result.resultItem && result.sentimentIndex) {
|
|
268
|
+
const sentimentIndex = result.sentimentIndex;
|
|
269
|
+
const resultItem = result.resultItem;
|
|
270
|
+
returnData[sentimentIndex].push(resultItem);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
if (i + batchSize < items.length && delayBetweenBatches > 0) {
|
|
274
|
+
await (0, import_n8n_workflow.sleep)(delayBetweenBatches);
|
|
219
275
|
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
276
|
+
}
|
|
277
|
+
} else {
|
|
278
|
+
for (let i = 0; i < items.length; i++) {
|
|
279
|
+
try {
|
|
280
|
+
const sentimentCategories = this.getNodeParameter(
|
|
281
|
+
"options.categories",
|
|
282
|
+
i,
|
|
283
|
+
DEFAULT_CATEGORIES
|
|
225
284
|
);
|
|
226
|
-
|
|
227
|
-
|
|
285
|
+
const categories = sentimentCategories.split(",").map((cat) => cat.trim()).filter(Boolean);
|
|
286
|
+
if (categories.length === 0) {
|
|
287
|
+
throw new import_n8n_workflow.NodeOperationError(this.getNode(), "No sentiment categories provided", {
|
|
288
|
+
itemIndex: i
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
if (returnData.length === 0) {
|
|
292
|
+
returnData.push(...Array.from({ length: categories.length }, () => []));
|
|
293
|
+
}
|
|
294
|
+
const options = this.getNodeParameter("options", i, {});
|
|
295
|
+
const schema = import_zod.z.object({
|
|
296
|
+
sentiment: import_zod.z.enum(categories),
|
|
297
|
+
strength: import_zod.z.number().min(0).max(1).describe("Strength score for sentiment in relation to the category"),
|
|
298
|
+
confidence: import_zod.z.number().min(0).max(1)
|
|
299
|
+
});
|
|
300
|
+
const structuredParser = import_output_parsers.StructuredOutputParser.fromZodSchema(schema);
|
|
301
|
+
const parser = options.enableAutoFixing ? import_output_parsers.OutputFixingParser.fromLLM(llm, structuredParser) : structuredParser;
|
|
302
|
+
const systemPromptTemplate = import_prompts.SystemMessagePromptTemplate.fromTemplate(
|
|
303
|
+
`${options.systemPromptTemplate ?? DEFAULT_SYSTEM_PROMPT_TEMPLATE}
|
|
304
|
+
{format_instructions}`
|
|
305
|
+
);
|
|
306
|
+
const input = this.getNodeParameter("inputText", i);
|
|
307
|
+
const inputPrompt = new import_messages.HumanMessage(input);
|
|
308
|
+
const messages = [
|
|
309
|
+
await systemPromptTemplate.format({
|
|
310
|
+
categories: sentimentCategories,
|
|
311
|
+
format_instructions: parser.getFormatInstructions()
|
|
312
|
+
}),
|
|
313
|
+
inputPrompt
|
|
314
|
+
];
|
|
315
|
+
const prompt = import_prompts.ChatPromptTemplate.fromMessages(messages);
|
|
316
|
+
const chain = prompt.pipe(llm).pipe(parser).withConfig((0, import_tracing.getTracingConfig)(this));
|
|
317
|
+
try {
|
|
318
|
+
const output = await chain.invoke(messages);
|
|
319
|
+
const sentimentIndex = categories.findIndex(
|
|
320
|
+
(s) => s.toLowerCase() === output.sentiment.toLowerCase()
|
|
321
|
+
);
|
|
322
|
+
if (sentimentIndex !== -1) {
|
|
323
|
+
const resultItem = { ...items[i] };
|
|
324
|
+
const sentimentAnalysis = {
|
|
325
|
+
category: output.sentiment
|
|
326
|
+
};
|
|
327
|
+
if (options.includeDetailedResults) {
|
|
328
|
+
sentimentAnalysis.strength = output.strength;
|
|
329
|
+
sentimentAnalysis.confidence = output.confidence;
|
|
330
|
+
}
|
|
331
|
+
resultItem.json = {
|
|
332
|
+
...resultItem.json,
|
|
333
|
+
sentimentAnalysis
|
|
334
|
+
};
|
|
335
|
+
returnData[sentimentIndex].push(resultItem);
|
|
336
|
+
}
|
|
337
|
+
} catch (error) {
|
|
338
|
+
throw new import_n8n_workflow.NodeOperationError(
|
|
339
|
+
this.getNode(),
|
|
340
|
+
"Error during parsing of LLM output, please check your LLM model and configuration",
|
|
341
|
+
{
|
|
342
|
+
itemIndex: i
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
} catch (error) {
|
|
347
|
+
if (this.continueOnFail()) {
|
|
348
|
+
const executionErrorData = this.helpers.constructExecutionMetaData(
|
|
349
|
+
this.helpers.returnJsonArray({ error: error.message }),
|
|
350
|
+
{ itemData: { item: i } }
|
|
351
|
+
);
|
|
352
|
+
returnData[0].push(...executionErrorData);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
throw error;
|
|
228
356
|
}
|
|
229
|
-
throw error;
|
|
230
357
|
}
|
|
231
358
|
}
|
|
232
359
|
return returnData;
|