fix(OpenAI Node): Use new model for text classification (#22130)

This commit is contained in:
RomanDavydchuk
2025-11-21 17:02:10 +00:00
committed by GitHub
parent 731a6397f7
commit 7c4771e623
4 changed files with 116 additions and 4 deletions
@@ -15,7 +15,7 @@ export class OpenAi extends VersionedNodeType {
name: 'openAi',
icon: { light: 'file:openAi.svg', dark: 'file:openAi.dark.svg' },
group: ['transform'],
defaultVersion: 2,
defaultVersion: 2.1,
subtitle: `={{(${prettifyOperation})($parameter.resource, $parameter.operation)}}`,
description: 'Message an assistant or GPT, analyze images, generate audio, etc.',
codex: {
@@ -55,6 +55,7 @@ export class OpenAi extends VersionedNodeType {
1.7: new OpenAiV1(baseDescription),
1.8: new OpenAiV1(baseDescription),
2: new OpenAiV2(baseDescription),
2.1: new OpenAiV2(baseDescription),
};
super(nodeVersions, baseDescription);
@@ -0,0 +1,102 @@
import { mockDeep } from 'jest-mock-extended';
import type { IExecuteFunctions, INode } from 'n8n-workflow';
import * as transport from '../../../../transport';
import * as classify from '../../../../v2/actions/text/classify.operation';
describe('OpenAI Classify Operation', () => {
const executeFunctions = mockDeep<IExecuteFunctions>();
const node = {
id: '123',
name: 'OpenAI Node',
type: '@n8n/n8n-nodes-langchain.openAi',
typeVersion: 2.1,
position: [0, 0],
parameters: {},
} as INode;
const apiRequestSpy = jest.spyOn(transport, 'apiRequest');
beforeEach(() => {
jest.resetAllMocks();
});
it('should use omni-moderation-latest model when version is 2.1', async () => {
executeFunctions.getNode.mockReturnValue(node);
executeFunctions.getNodeParameter.mockImplementation((param: string) => {
const params = {
input: 'Lorem ipsum',
simplify: false,
};
return params[param as keyof typeof params];
});
apiRequestSpy.mockResolvedValueOnce({ results: [{ flagged: true }] });
const result = await classify.execute.call(executeFunctions, 0);
expect(apiRequestSpy).toHaveBeenCalledWith('POST', '/moderations', {
body: { input: 'Lorem ipsum', model: 'omni-moderation-latest' },
});
expect(result).toEqual([
{
json: { flagged: true },
pairedItem: { item: 0 },
},
]);
});
it('should use text-moderation-stable model when version is less than 2.1 and useStableModel is true', async () => {
executeFunctions.getNode.mockReturnValue({
...node,
typeVersion: 2,
});
executeFunctions.getNodeParameter.mockImplementation((param: string) => {
const params = {
input: 'Lorem ipsum',
simplify: false,
options: { useStableModel: true },
};
return params[param as keyof typeof params];
});
apiRequestSpy.mockResolvedValueOnce({ results: [{ flagged: true }] });
const result = await classify.execute.call(executeFunctions, 0);
expect(apiRequestSpy).toHaveBeenCalledWith('POST', '/moderations', {
body: { input: 'Lorem ipsum', model: 'text-moderation-stable' },
});
expect(result).toEqual([
{
json: { flagged: true },
pairedItem: { item: 0 },
},
]);
});
it('should use text-moderation-latest model when version is less than 2.1 and useStableModel is false', async () => {
executeFunctions.getNode.mockReturnValue({
...node,
typeVersion: 2,
});
executeFunctions.getNodeParameter.mockImplementation((param: string) => {
const params = {
input: 'Lorem ipsum',
simplify: false,
options: { useStableModel: false },
};
return params[param as keyof typeof params];
});
apiRequestSpy.mockResolvedValueOnce({ results: [{ flagged: true }] });
const result = await classify.execute.call(executeFunctions, 0);
expect(apiRequestSpy).toHaveBeenCalledWith('POST', '/moderations', {
body: { input: 'Lorem ipsum', model: 'text-moderation-latest' },
});
expect(result).toEqual([
{
json: { flagged: true },
pairedItem: { item: 0 },
},
]);
});
});
@@ -23,7 +23,7 @@ export class OpenAiV2 implements INodeType {
constructor(baseDescription: INodeTypeBaseDescription) {
this.description = {
...baseDescription,
version: [2],
version: [2, 2.1],
defaults: {
name: 'OpenAI',
},
@@ -38,6 +38,11 @@ const properties: INodeProperties[] = [
'Whether to use the stable version of the model instead of the latest version, accuracy may be slightly lower',
},
],
displayOptions: {
show: {
'@version': [{ _cnd: { lt: 2.1 } }],
},
},
},
];
@@ -52,8 +57,12 @@ export const description = updateDisplayOptions(displayOptions, properties);
export async function execute(this: IExecuteFunctions, i: number): Promise<INodeExecutionData[]> {
const input = this.getNodeParameter('input', i) as string;
const options = this.getNodeParameter('options', i);
const model = options.useStableModel ? 'text-moderation-stable' : 'text-moderation-latest';
const version = this.getNode().typeVersion;
let model = 'omni-moderation-latest';
if (version < 2.1) {
const options = this.getNodeParameter('options', i);
model = options.useStableModel ? 'text-moderation-stable' : 'text-moderation-latest';
}
const body = {
input,