Skip to content

Commit 5aa6054

Browse files
authored
fix(editor): Differentiate $fromAI overrides within lists (#14696)
1 parent acf2453 commit 5aa6054

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

packages/frontend/editor-ui/src/utils/fromAIOverrideUtils.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { INodeUi } from '@/Interface';
22
import type { FromAIOverride, OverrideContext } from './fromAIOverrideUtils';
33
import {
4+
buildUniqueName,
45
buildValueFromOverride,
56
fromAIExtraProps,
67
isFromAIOverrideValue,
@@ -213,3 +214,40 @@ describe('FromAiOverride', () => {
213214
);
214215
});
215216
});
217+
218+
describe('buildUniqueName', () => {
219+
test.each<[string, string, string]>([
220+
['no list segments', 'parameters.someParameter', DISPLAY_NAME],
221+
[
222+
'list segments in the path',
223+
'parameters.someList[0].someParameter',
224+
'someList0_' + DISPLAY_NAME,
225+
],
226+
[
227+
'multiple list segments in the path',
228+
'parameters.someList[0].nestedList[1].someParameter',
229+
'someList0_nestedList1_' + DISPLAY_NAME,
230+
],
231+
[
232+
'paths without parameters',
233+
'someList[0].nestedList[1]',
234+
'someList0_nestedList1_' + DISPLAY_NAME,
235+
],
236+
['empty paths', '', DISPLAY_NAME],
237+
[
238+
'path with multiple lists and segment exceeding 63 characters',
239+
'parameters.someLoooooongList[0].nestedListWithAVeryLongNameThatExceedsTheLimit[1].someParameter',
240+
`someLoooooongList0_nestedListWithAVeryLongNameThatExceedsTheLimit1_${DISPLAY_NAME}`.slice(
241+
-63,
242+
),
243+
],
244+
[
245+
'path with multiple long segments and truncation',
246+
'parameters.someExtremelyLongListNameThatExceedsTheLimit.anotherLongSegmentName.finalParameter',
247+
DISPLAY_NAME,
248+
],
249+
])('should build a unique name with %s', (_description, path, expected) => {
250+
const context = makeContext('value', path);
251+
expect(buildUniqueName(context)).toEqual(expected);
252+
});
253+
});

packages/frontend/editor-ui/src/utils/fromAIOverrideUtils.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,38 @@ function getBestQuoteChar(description: string) {
119119
return "'";
120120
}
121121

122+
// Note that this is not *technically* unique, as two lists with the
123+
// same list name and the same property display name could theoretically
124+
// exist within one node. However, this is unlikely to happen in practice.
125+
export function buildUniqueName(props: Pick<OverrideContext, 'parameter' | 'path'>) {
126+
const path = props.path.split('.');
127+
128+
// include any list segments in the path (e.g. .myListName[0].) for uniqueness
129+
// but drop brackets to avoid token limits
130+
const filteredPaths = path
131+
.filter((x) => /\[\d+\]/i.test(x))
132+
.map((x) => x.replaceAll(/[\[\]]/gi, ''));
133+
let result = [...filteredPaths, props.parameter.displayName].join('_');
134+
135+
// Langchain requires the name to be <64 characters
136+
if (filteredPaths.length > 1) {
137+
// Prefer clipping the list names over the display name
138+
result = result.slice(-63);
139+
} else {
140+
result = result.slice(0, 63);
141+
}
142+
143+
return result;
144+
}
145+
122146
export function buildValueFromOverride(
123147
override: FromAIOverride,
124-
props: Pick<OverrideContext, 'parameter'>,
148+
props: Pick<OverrideContext, 'parameter' | 'path'>,
125149
includeMarker: boolean,
126150
) {
127151
const { extraPropValues, extraProps } = override;
128152
const marker = includeMarker ? `${FROM_AI_AUTO_GENERATED_MARKER} ` : '';
129-
const key = sanitizeFromAiParameterName(props.parameter.displayName);
153+
const key = sanitizeFromAiParameterName(buildUniqueName(props));
130154
const description =
131155
extraPropValues?.description?.toString() ?? extraProps.description.initialValue;
132156

0 commit comments

Comments
 (0)