-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/** @type {import('jest').Config} */ | ||
module.exports = require('../../../jest.config'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import type { IExecuteFunctions, INodeType } from 'n8n-workflow'; | ||
import { router } from './actions/router'; | ||
import { versionDescription } from './actions/versionDescription'; | ||
import { listSearch, loadOptions } from './methods'; | ||
|
||
export class OpenAi implements INodeType { | ||
description = versionDescription; | ||
|
||
methods = { | ||
listSearch, | ||
loadOptions, | ||
}; | ||
|
||
async execute(this: IExecuteFunctions) { | ||
return await router.call(this); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
import type { | ||
INodeProperties, | ||
IExecuteFunctions, | ||
INodeExecutionData, | ||
IDataObject, | ||
} from 'n8n-workflow'; | ||
import { NodeOperationError, updateDisplayOptions } from 'n8n-workflow'; | ||
import { apiRequest } from '../../transport'; | ||
import { modelRLC } from '../descriptions'; | ||
|
||
const properties: INodeProperties[] = [ | ||
modelRLC, | ||
{ | ||
displayName: 'Name', | ||
name: 'name', | ||
type: 'string', | ||
default: '', | ||
description: 'The name of the assistant. The maximum length is 256 characters.', | ||
placeholder: 'e.g. My Assistant', | ||
required: true, | ||
}, | ||
{ | ||
displayName: 'Description', | ||
name: 'description', | ||
type: 'string', | ||
default: '', | ||
description: 'The description of the assistant. The maximum length is 512 characters.', | ||
placeholder: 'e.g. My personal assistant', | ||
}, | ||
{ | ||
displayName: 'Instructions', | ||
name: 'instructions', | ||
type: 'string', | ||
description: | ||
'The system instructions that the assistant uses. The maximum length is 32768 characters.', | ||
default: '', | ||
typeOptions: { | ||
rows: 2, | ||
}, | ||
}, | ||
{ | ||
displayName: 'Code Interpreter', | ||
name: 'codeInterpreter', | ||
type: 'boolean', | ||
default: false, | ||
description: | ||
'Whether to enable the code interpreter that allows the assistants to write and run Python code in a sandboxed execution environment, find more <a href="https://platform.openai.com/docs/assistants/tools/code-interpreter" target="_blank">here</a>', | ||
}, | ||
{ | ||
displayName: 'Knowledge Retrieval', | ||
name: 'knowledgeRetrieval', | ||
type: 'boolean', | ||
default: false, | ||
description: | ||
'Whether to augments the assistant with knowledge from outside its model, such as proprietary product information or documents, find more <a href="https://platform.openai.com/docs/assistants/tools/knowledge-retrieval" target="_blank">here</a>', | ||
}, | ||
//we want to display Files selector only when codeInterpreter true or knowledgeRetrieval true or both | ||
{ | ||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-multi-options | ||
displayName: 'Files', | ||
name: 'file_ids', | ||
type: 'multiOptions', | ||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-multi-options | ||
description: | ||
'The files to be used by the assistant, there can be a maximum of 20 files attached to the assistant', | ||
typeOptions: { | ||
loadOptionsMethod: 'getFiles', | ||
}, | ||
default: [], | ||
hint: "Add more files by using the 'Upload a File' operation", | ||
displayOptions: { | ||
show: { | ||
codeInterpreter: [true], | ||
}, | ||
hide: { | ||
knowledgeRetrieval: [true], | ||
}, | ||
}, | ||
}, | ||
{ | ||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-multi-options | ||
displayName: 'Files', | ||
name: 'file_ids', | ||
type: 'multiOptions', | ||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-multi-options | ||
description: | ||
'The files to be used by the assistant, there can be a maximum of 20 files attached to the assistant', | ||
typeOptions: { | ||
loadOptionsMethod: 'getFiles', | ||
}, | ||
default: [], | ||
hint: "Add more files by using the 'Upload a File' operation", | ||
displayOptions: { | ||
show: { | ||
knowledgeRetrieval: [true], | ||
}, | ||
hide: { | ||
codeInterpreter: [true], | ||
}, | ||
}, | ||
}, | ||
{ | ||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-multi-options | ||
displayName: 'Files', | ||
name: 'file_ids', | ||
type: 'multiOptions', | ||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-multi-options | ||
description: | ||
'The files to be used by the assistant, there can be a maximum of 20 files attached to the assistant', | ||
typeOptions: { | ||
loadOptionsMethod: 'getFiles', | ||
}, | ||
default: [], | ||
hint: "Add more files by using the 'Upload a File' operation", | ||
displayOptions: { | ||
show: { | ||
knowledgeRetrieval: [true], | ||
codeInterpreter: [true], | ||
}, | ||
}, | ||
}, | ||
{ | ||
displayName: "Add custom n8n tools when using the 'Message Assistant' operation", | ||
name: 'noticeTools', | ||
type: 'notice', | ||
default: '', | ||
}, | ||
{ | ||
displayName: 'Options', | ||
name: 'options', | ||
placeholder: 'Add Option', | ||
type: 'collection', | ||
default: {}, | ||
options: [ | ||
{ | ||
displayName: 'Fail if Assistant Already Exists', | ||
name: 'failIfExists', | ||
type: 'boolean', | ||
default: false, | ||
description: | ||
'Whether to fail an operation if the assistant with the same name already exists', | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
const displayOptions = { | ||
show: { | ||
operation: ['create'], | ||
resource: ['assistant'], | ||
}, | ||
}; | ||
|
||
export const description = updateDisplayOptions(displayOptions, properties); | ||
|
||
export async function execute(this: IExecuteFunctions, i: number): Promise<INodeExecutionData[]> { | ||
const model = this.getNodeParameter('modelId', i, '', { extractValue: true }) as string; | ||
const name = this.getNodeParameter('name', i) as string; | ||
const assistantDescription = this.getNodeParameter('description', i) as string; | ||
const instructions = this.getNodeParameter('instructions', i) as string; | ||
const codeInterpreter = this.getNodeParameter('codeInterpreter', i) as boolean; | ||
const knowledgeRetrieval = this.getNodeParameter('knowledgeRetrieval', i) as boolean; | ||
const file_ids = this.getNodeParameter('file_ids', i, []) as string[]; | ||
const options = this.getNodeParameter('options', i, {}); | ||
|
||
if (options.failIfExists) { | ||
const assistants: string[] = []; | ||
|
||
let has_more = true; | ||
let after: string | undefined; | ||
|
||
do { | ||
const response = await apiRequest.call(this, 'GET', '/assistants', { | ||
Check warning on line 173 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
|
||
headers: { | ||
'OpenAI-Beta': 'assistants=v1', | ||
}, | ||
qs: { | ||
limit: 100, | ||
after, | ||
}, | ||
}); | ||
|
||
for (const assistant of response.data || []) { | ||
Check warning on line 183 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
|
||
assistants.push(assistant.name); | ||
Check warning on line 184 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
Check warning on line 184 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
Check warning on line 184 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (20.x)
|
||
} | ||
|
||
has_more = response.has_more; | ||
Check warning on line 187 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
Check warning on line 187 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
Check warning on line 187 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (20.x)
|
||
|
||
if (has_more) { | ||
after = response.last_id as string; | ||
Check warning on line 190 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
|
||
} else { | ||
break; | ||
} | ||
} while (has_more); | ||
|
||
if (assistants.includes(name)) { | ||
throw new NodeOperationError( | ||
this.getNode(), | ||
`An assistant with the same name '${name}' already exists`, | ||
{ itemIndex: i }, | ||
); | ||
} | ||
} | ||
|
||
if (file_ids.length > 20) { | ||
throw new NodeOperationError( | ||
this.getNode(), | ||
'The maximum number of files that can be attached to the assistant is 20', | ||
{ itemIndex: i }, | ||
); | ||
} | ||
|
||
const body: IDataObject = { | ||
model, | ||
name, | ||
description: assistantDescription, | ||
instructions, | ||
file_ids, | ||
}; | ||
|
||
const tools = []; | ||
|
||
if (codeInterpreter) { | ||
tools.push({ | ||
type: 'code_interpreter', | ||
}); | ||
} | ||
|
||
if (knowledgeRetrieval) { | ||
tools.push({ | ||
type: 'retrieval', | ||
}); | ||
} | ||
|
||
if (tools.length) { | ||
body.tools = tools; | ||
} | ||
|
||
const response = await apiRequest.call(this, 'POST', '/assistants', { | ||
Check warning on line 239 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
|
||
body, | ||
headers: { | ||
'OpenAI-Beta': 'assistants=v1', | ||
}, | ||
}); | ||
|
||
return [ | ||
{ | ||
json: response, | ||
Check warning on line 248 in packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/actions/assistant/create.operation.ts GitHub Actions / Lint changes (18.x)
|
||
pairedItem: { item: i }, | ||
}, | ||
]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow'; | ||
import { updateDisplayOptions } from 'n8n-workflow'; | ||
import { apiRequest } from '../../transport'; | ||
import { assistantRLC } from '../descriptions'; | ||
|
||
const properties: INodeProperties[] = [assistantRLC]; | ||
|
||
const displayOptions = { | ||
show: { | ||
operation: ['deleteAssistant'], | ||
resource: ['assistant'], | ||
}, | ||
}; | ||
|
||
export const description = updateDisplayOptions(displayOptions, properties); | ||
|
||
export async function execute(this: IExecuteFunctions, i: number): Promise<INodeExecutionData[]> { | ||
const assistantId = this.getNodeParameter('assistantId', i, '', { extractValue: true }) as string; | ||
|
||
const response = await apiRequest.call(this, 'DELETE', `/assistants/${assistantId}`, { | ||
headers: { | ||
'OpenAI-Beta': 'assistants=v1', | ||
}, | ||
}); | ||
|
||
return [ | ||
{ | ||
json: response, | ||
pairedItem: { item: i }, | ||
}, | ||
]; | ||
} |