mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 19:32:15 +00:00
fix(editor): Differentiate $fromAI overrides within lists (#14696)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import type { FromAIOverride, OverrideContext } from './fromAIOverrideUtils';
|
||||
import {
|
||||
buildUniqueName,
|
||||
buildValueFromOverride,
|
||||
fromAIExtraProps,
|
||||
isFromAIOverrideValue,
|
||||
@@ -213,3 +214,40 @@ describe('FromAiOverride', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildUniqueName', () => {
|
||||
test.each<[string, string, string]>([
|
||||
['no list segments', 'parameters.someParameter', DISPLAY_NAME],
|
||||
[
|
||||
'list segments in the path',
|
||||
'parameters.someList[0].someParameter',
|
||||
'someList0_' + DISPLAY_NAME,
|
||||
],
|
||||
[
|
||||
'multiple list segments in the path',
|
||||
'parameters.someList[0].nestedList[1].someParameter',
|
||||
'someList0_nestedList1_' + DISPLAY_NAME,
|
||||
],
|
||||
[
|
||||
'paths without parameters',
|
||||
'someList[0].nestedList[1]',
|
||||
'someList0_nestedList1_' + DISPLAY_NAME,
|
||||
],
|
||||
['empty paths', '', DISPLAY_NAME],
|
||||
[
|
||||
'path with multiple lists and segment exceeding 63 characters',
|
||||
'parameters.someLoooooongList[0].nestedListWithAVeryLongNameThatExceedsTheLimit[1].someParameter',
|
||||
`someLoooooongList0_nestedListWithAVeryLongNameThatExceedsTheLimit1_${DISPLAY_NAME}`.slice(
|
||||
-63,
|
||||
),
|
||||
],
|
||||
[
|
||||
'path with multiple long segments and truncation',
|
||||
'parameters.someExtremelyLongListNameThatExceedsTheLimit.anotherLongSegmentName.finalParameter',
|
||||
DISPLAY_NAME,
|
||||
],
|
||||
])('should build a unique name with %s', (_description, path, expected) => {
|
||||
const context = makeContext('value', path);
|
||||
expect(buildUniqueName(context)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -119,14 +119,38 @@ function getBestQuoteChar(description: string) {
|
||||
return "'";
|
||||
}
|
||||
|
||||
// Note that this is not *technically* unique, as two lists with the
|
||||
// same list name and the same property display name could theoretically
|
||||
// exist within one node. However, this is unlikely to happen in practice.
|
||||
export function buildUniqueName(props: Pick<OverrideContext, 'parameter' | 'path'>) {
|
||||
const path = props.path.split('.');
|
||||
|
||||
// include any list segments in the path (e.g. .myListName[0].) for uniqueness
|
||||
// but drop brackets to avoid token limits
|
||||
const filteredPaths = path
|
||||
.filter((x) => /\[\d+\]/i.test(x))
|
||||
.map((x) => x.replaceAll(/[\[\]]/gi, ''));
|
||||
let result = [...filteredPaths, props.parameter.displayName].join('_');
|
||||
|
||||
// Langchain requires the name to be <64 characters
|
||||
if (filteredPaths.length > 1) {
|
||||
// Prefer clipping the list names over the display name
|
||||
result = result.slice(-63);
|
||||
} else {
|
||||
result = result.slice(0, 63);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function buildValueFromOverride(
|
||||
override: FromAIOverride,
|
||||
props: Pick<OverrideContext, 'parameter'>,
|
||||
props: Pick<OverrideContext, 'parameter' | 'path'>,
|
||||
includeMarker: boolean,
|
||||
) {
|
||||
const { extraPropValues, extraProps } = override;
|
||||
const marker = includeMarker ? `${FROM_AI_AUTO_GENERATED_MARKER} ` : '';
|
||||
const key = sanitizeFromAiParameterName(props.parameter.displayName);
|
||||
const key = sanitizeFromAiParameterName(buildUniqueName(props));
|
||||
const description =
|
||||
extraPropValues?.description?.toString() ?? extraProps.description.initialValue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user