feat(OpenAI Chat Model Node): Add reasoning effort option to control the amount of reasoning tokens to use (#13103)

This commit is contained in:
jeanpaul 2025-02-06 17:21:34 +01:00 committed by GitHub
parent fff46fa75e
commit 76e0c99613
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -264,6 +264,38 @@ export class LmChatOpenAi implements INodeType {
'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.', 'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',
type: 'number', type: 'number',
}, },
{
displayName: 'Reasoning Effort',
name: 'reasoningEffort',
default: 'medium',
description:
'Controls the amount of reasoning tokens to use. A value of "low" will favor speed and economical token usage, "high" will favor more complete reasoning at the cost of more tokens generated and slower responses.',
type: 'options',
options: [
{
name: 'Low',
value: 'low',
description: 'Favors speed and economical token usage',
},
{
name: 'Medium',
value: 'medium',
description: 'Balance between speed and reasoning accuracy',
},
{
name: 'High',
value: 'high',
description:
'Favors more complete reasoning at the cost of more tokens generated and slower responses',
},
],
displayOptions: {
show: {
// reasoning_effort is only available on o1, o1-versioned, or on o3-mini and beyond. Not on o1-mini or other GPT-models.
'/model': [{ _cnd: { regex: '(^o1([-\\d]+)?$)|(^o[3-9].*)' } }],
},
},
},
{ {
displayName: 'Timeout', displayName: 'Timeout',
name: 'timeout', name: 'timeout',
@ -311,6 +343,7 @@ export class LmChatOpenAi implements INodeType {
temperature?: number; temperature?: number;
topP?: number; topP?: number;
responseFormat?: 'text' | 'json_object'; responseFormat?: 'text' | 'json_object';
reasoningEffort?: 'low' | 'medium' | 'high';
}; };
const configuration: ClientOptions = {}; const configuration: ClientOptions = {};
@ -320,6 +353,15 @@ export class LmChatOpenAi implements INodeType {
configuration.baseURL = credentials.url as string; configuration.baseURL = credentials.url as string;
} }
// Extra options to send to OpenAI, that are not directly supported by LangChain
const modelKwargs: {
response_format?: object;
reasoning_effort?: 'low' | 'medium' | 'high';
} = {};
if (options.responseFormat) modelKwargs.response_format = { type: options.responseFormat };
if (options.reasoningEffort && ['low', 'medium', 'high'].includes(options.reasoningEffort))
modelKwargs.reasoning_effort = options.reasoningEffort;
const model = new ChatOpenAI({ const model = new ChatOpenAI({
openAIApiKey: credentials.apiKey as string, openAIApiKey: credentials.apiKey as string,
modelName, modelName,
@ -328,11 +370,7 @@ export class LmChatOpenAi implements INodeType {
maxRetries: options.maxRetries ?? 2, maxRetries: options.maxRetries ?? 2,
configuration, configuration,
callbacks: [new N8nLlmTracing(this)], callbacks: [new N8nLlmTracing(this)],
modelKwargs: options.responseFormat modelKwargs,
? {
response_format: { type: options.responseFormat },
}
: undefined,
onFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler), onFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler),
}); });