From fd833ec0794e4c1463889e72926ffb66f92752ab Mon Sep 17 00:00:00 2001 From: jeanpaul Date: Fri, 12 Jul 2024 17:11:08 +0200 Subject: [PATCH] feat(Text Classifier Node): Change fallback option to a drop-down (no-changelog) (#10039) --- .../TextClassifier/TextClassifier.node.ts | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/packages/@n8n/nodes-langchain/nodes/chains/TextClassifier/TextClassifier.node.ts b/packages/@n8n/nodes-langchain/nodes/chains/TextClassifier/TextClassifier.node.ts index 9c1e9824d9..22e8ff4aa7 100644 --- a/packages/@n8n/nodes-langchain/nodes/chains/TextClassifier/TextClassifier.node.ts +++ b/packages/@n8n/nodes-langchain/nodes/chains/TextClassifier/TextClassifier.node.ts @@ -21,11 +21,11 @@ const SYSTEM_PROMPT_TEMPLATE = const configuredOutputs = (parameters: INodeParameters) => { const categories = ((parameters.categories as IDataObject)?.categories as IDataObject[]) ?? []; - const fallback = (parameters.options as IDataObject)?.fallback as boolean; + const fallback = (parameters.options as IDataObject)?.fallback as string; const ret = categories.map((cat) => { return { type: NodeConnectionType.Main, displayName: cat.category }; }); - if (fallback) ret.push({ type: NodeConnectionType.Main, displayName: 'Other' }); + if (fallback === 'other') ret.push({ type: NodeConnectionType.Main, displayName: 'Other' }); return ret; }; @@ -122,11 +122,23 @@ export class TextClassifier implements INodeType { default: false, }, { - displayName: 'Add Fallback Option', + displayName: 'When No Clear Match', name: 'fallback', - type: 'boolean', - default: false, - description: 'Whether to add a "fallback" option if no other categories match', + type: 'options', + default: 'discard', + description: 'What to do with items that don’t match the categories exactly', + options: [ + { + name: 'Discard Item', + value: 'discard', + description: 'Ignore the item and drop it from the output', + }, + { + name: "Output on Extra, 'Other' Branch", + value: 'other', + description: "Create a separate output branch called 'Other'", + }, + ], }, { displayName: 'System Prompt Template', @@ -158,11 +170,11 @@ export class TextClassifier implements INodeType { const options = this.getNodeParameter('options', 0, {}) as { multiClass: boolean; - fallback: boolean; + fallback?: string; systemPromptTemplate?: string; }; const multiClass = options?.multiClass ?? false; - const fallback = options?.fallback ?? false; + const fallback = options?.fallback ?? 'discard'; const schemaEntries = categories.map((cat) => [ cat.category, @@ -172,7 +184,7 @@ export class TextClassifier implements INodeType { `Should be true if the input has category "${cat.category}" (description: ${cat.description})`, ), ]); - if (fallback) + if (fallback === 'other') schemaEntries.push([ 'fallback', z.boolean().describe('Should be true if none of the other categories apply'), @@ -184,9 +196,11 @@ export class TextClassifier implements INodeType { const multiClassPrompt = multiClass ? 'Categories are not mutually exclusive, and multiple can be true' : 'Categories are mutually exclusive, and only one can be true'; - const fallbackPrompt = fallback - ? 'If no categories apply, select the "fallback" option.' - : 'One of the options must always be true.'; + + const fallbackPrompt = { + other: 'If no categories apply, select the "fallback" option.', + discard: 'If there is not a very fitting category, select none of the categories.', + }[fallback]; const systemPromptTemplate = SystemMessagePromptTemplate.fromTemplate( `${options.systemPromptTemplate ?? SYSTEM_PROMPT_TEMPLATE} @@ -196,7 +210,7 @@ ${fallbackPrompt}`, ); const returnData: INodeExecutionData[][] = Array.from( - { length: categories.length + (fallback ? 1 : 0) }, + { length: categories.length + (fallback === 'other' ? 1 : 0) }, (_) => [], ); for (let itemIdx = 0; itemIdx < items.length; itemIdx++) { @@ -216,7 +230,8 @@ ${fallbackPrompt}`, categories.forEach((cat, idx) => { if (output[cat.category]) returnData[idx].push(items[itemIdx]); }); - if (fallback && output.fallback) returnData[returnData.length - 1].push(items[itemIdx]); + if (fallback === 'other' && output.fallback) + returnData[returnData.length - 1].push(items[itemIdx]); } return returnData; }