mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix: OpenAI Node function to preserve original tools after node execution (#8872)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com> Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
parent
6e99e26f69
commit
054a4fce1a
|
@ -120,7 +120,8 @@ const properties: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: "Add custom n8n tools when using the 'Message Assistant' operation",
|
displayName:
|
||||||
|
'Add custom n8n tools when you <i>message</i> your assistant (rather than when creating it)',
|
||||||
name: 'noticeTools',
|
name: 'noticeTools',
|
||||||
type: 'notice',
|
type: 'notice',
|
||||||
default: '',
|
default: '',
|
||||||
|
|
|
@ -84,6 +84,19 @@ const properties: INodeProperties[] = [
|
||||||
description: 'Maximum amount of time a request is allowed to take in milliseconds',
|
description: 'Maximum amount of time a request is allowed to take in milliseconds',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Preserve Original Tools',
|
||||||
|
name: 'preserveOriginalTools',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
description:
|
||||||
|
'Whether to preserve the original tools of the assistant after the execution of this node, otherwise the tools will be replaced with the connected tools, if any, default is true',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'@version': [{ _cnd: { gte: 1.3 } }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -123,6 +136,7 @@ export async function execute(this: IExecuteFunctions, i: number): Promise<INode
|
||||||
baseURL?: string;
|
baseURL?: string;
|
||||||
maxRetries: number;
|
maxRetries: number;
|
||||||
timeout: number;
|
timeout: number;
|
||||||
|
preserveOriginalTools?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const client = new OpenAIClient({
|
const client = new OpenAIClient({
|
||||||
|
@ -135,21 +149,22 @@ export async function execute(this: IExecuteFunctions, i: number): Promise<INode
|
||||||
const agent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });
|
const agent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });
|
||||||
|
|
||||||
const tools = await getConnectedTools(this, nodeVersion > 1);
|
const tools = await getConnectedTools(this, nodeVersion > 1);
|
||||||
|
let assistantTools;
|
||||||
|
|
||||||
if (tools.length) {
|
if (tools.length) {
|
||||||
const transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];
|
const transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];
|
||||||
const nativeToolsParsed: OpenAIToolType = [];
|
const nativeToolsParsed: OpenAIToolType = [];
|
||||||
|
|
||||||
const assistant = await client.beta.assistants.retrieve(assistantId);
|
assistantTools = (await client.beta.assistants.retrieve(assistantId)).tools;
|
||||||
|
|
||||||
const useCodeInterpreter = assistant.tools.some((tool) => tool.type === 'code_interpreter');
|
const useCodeInterpreter = assistantTools.some((tool) => tool.type === 'code_interpreter');
|
||||||
if (useCodeInterpreter) {
|
if (useCodeInterpreter) {
|
||||||
nativeToolsParsed.push({
|
nativeToolsParsed.push({
|
||||||
type: 'code_interpreter',
|
type: 'code_interpreter',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const useRetrieval = assistant.tools.some((tool) => tool.type === 'retrieval');
|
const useRetrieval = assistantTools.some((tool) => tool.type === 'retrieval');
|
||||||
if (useRetrieval) {
|
if (useRetrieval) {
|
||||||
nativeToolsParsed.push({
|
nativeToolsParsed.push({
|
||||||
type: 'retrieval',
|
type: 'retrieval',
|
||||||
|
@ -166,11 +181,21 @@ export async function execute(this: IExecuteFunctions, i: number): Promise<INode
|
||||||
tools: tools ?? [],
|
tools: tools ?? [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await agentExecutor.call({
|
const response = await agentExecutor.invoke({
|
||||||
content: input,
|
content: input,
|
||||||
signal: this.getExecutionCancelSignal(),
|
signal: this.getExecutionCancelSignal(),
|
||||||
timeout: options.timeout ?? 10000,
|
timeout: options.timeout ?? 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
options.preserveOriginalTools !== false &&
|
||||||
|
nodeVersion >= 1.3 &&
|
||||||
|
(assistantTools ?? [])?.length
|
||||||
|
) {
|
||||||
|
await client.beta.assistants.update(assistantId, {
|
||||||
|
tools: assistantTools,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return [{ json: response, pairedItem: { item: i } }];
|
return [{ json: response, pairedItem: { item: i } }];
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ export const versionDescription: INodeTypeDescription = {
|
||||||
name: 'openAi',
|
name: 'openAi',
|
||||||
icon: 'file:openAi.svg',
|
icon: 'file:openAi.svg',
|
||||||
group: ['transform'],
|
group: ['transform'],
|
||||||
version: [1, 1.1, 1.2],
|
version: [1, 1.1, 1.2, 1.3],
|
||||||
subtitle: `={{(${prettifyOperation})($parameter.resource, $parameter.operation)}}`,
|
subtitle: `={{(${prettifyOperation})($parameter.resource, $parameter.operation)}}`,
|
||||||
description: 'Message an assistant or GPT, analyze images, generate audio, etc.',
|
description: 'Message an assistant or GPT, analyze images, generate audio, etc.',
|
||||||
defaults: {
|
defaults: {
|
||||||
|
|
Loading…
Reference in a new issue