diff --git a/integrations/n8n/credentials/SkyvernApi.credentials.ts b/integrations/n8n/credentials/SkyvernApi.credentials.ts index 750405f8..4dc65292 100644 --- a/integrations/n8n/credentials/SkyvernApi.credentials.ts +++ b/integrations/n8n/credentials/SkyvernApi.credentials.ts @@ -1,5 +1,6 @@ import { IAuthenticateGeneric, + ICredentialTestRequest, ICredentialType, INodeProperties, } from 'n8n-workflow'; @@ -35,4 +36,10 @@ export class SkyvernApi implements ICredentialType { } }, }; + test: ICredentialTestRequest = { + request: { + baseURL: '={{$credentials?.baseUrl}}', + url: '/api/v1/organizations', + }, + }; } \ No newline at end of file diff --git a/integrations/n8n/nodes/Skyvern/Skyvern.node.ts b/integrations/n8n/nodes/Skyvern/Skyvern.node.ts index f405545e..10cdcce9 100644 --- a/integrations/n8n/nodes/Skyvern/Skyvern.node.ts +++ b/integrations/n8n/nodes/Skyvern/Skyvern.node.ts @@ -123,7 +123,7 @@ export class Skyvern implements INodeType { request: { baseURL: '={{$credentials.baseUrl}}', method: '={{ $value === "dispatch" ? "POST" : "GET" }}' as IHttpRequestMethods, - url: '={{"/api/" + ($parameter["taskOptions"]["engine"] ? $parameter["taskOptions"]["engine"] : "v2") + "/tasks"}}', + url: '={{"/v1/run/tasks"}}', }, send: { preSend: [ @@ -132,46 +132,11 @@ export class Skyvern implements INodeType { if (taskOperation === "get") return requestOptions; const taskOptions: IDataObject = this.getNodeParameter('taskOptions') as IDataObject; - if (taskOptions["engine"] !== "v1") return requestOptions; - - const credentials = await this.getCredentials('skyvernApi'); - const userPrompt = this.getNodeParameter('userPrompt'); - - // *** capture optional webhook URL *** - let webhookUrl: string | undefined; - try { - webhookUrl = this.getNodeParameter('webhookUrl') as string; - } catch (e) { - webhookUrl = undefined; - } - - const generateBody: IDataObject = { - prompt: userPrompt, - }; - - const response = await makeRequest(credentials['baseUrl'] + '/api/v1/generate/task', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'x-api-key': credentials['apiKey'], - }, - body: JSON.stringify(generateBody), - }); - if (!response.ok) { - throw new Error('Request to generate Task V1 failed'); // eslint-disable-line - } - - const data = await response.json(); - requestOptions.body = { - url: data.url, - navigation_goal: data.navigation_goal, - navigation_payload: data.navigation_payload, - data_extraction_goal: data.data_extraction_goal, - extracted_information_schema: data.extracted_information_schema, - } as IDataObject; - - if (webhookUrl) { - (requestOptions.body as IDataObject)['webhook_callback_url'] = webhookUrl; + const legacy_engine = taskOptions["engine"] as string | null + if (legacy_engine === "v1") { + (requestOptions.body as IDataObject)['engine'] = "skyvern-1.0"; + }else if (legacy_engine === "v2") { + (requestOptions.body as IDataObject)['engine'] = "skyvern-2.0"; } return requestOptions; }, @@ -196,7 +161,7 @@ export class Skyvern implements INodeType { routing: { request: { body: { - user_prompt: '={{$value}}', + prompt: '={{$value}}', }, }, }, @@ -222,7 +187,6 @@ export class Skyvern implements INodeType { }, }, }, - // *** New property: optional webhook URL for Task dispatch *** { displayName: 'Webhook Callback URL', description: 'Optional URL that Skyvern will call when the task finishes', @@ -239,7 +203,7 @@ export class Skyvern implements INodeType { routing: { request: { body: { - webhook_callback_url: '={{$value ? $value : undefined}}', + webhook_url: '={{$value ? $value : null}}', }, }, }, @@ -260,7 +224,7 @@ export class Skyvern implements INodeType { routing: { request: { method: 'GET', - url: '={{"/api/" + ($parameter["taskOptions"]["engine"] ? $parameter["taskOptions"]["engine"] : "v2") + "/tasks/" + $value}}', + url: '={{"/v1/runs/" + $value}}', }, }, }, @@ -273,10 +237,12 @@ export class Skyvern implements INodeType { default: {}, options: [ { - displayName: 'Engine', + displayName: 'Engine(Deprecated)', + description: 'Deprecated: please migrate to use "Engine" option', name: 'engine', type: 'options', - default: 'v2', + default: '', + required: false, options: [ { name: 'TaskV1', @@ -286,12 +252,45 @@ export class Skyvern implements INodeType { name: 'TaskV2', value: 'v2', }, + ], }, + { + displayName: 'Engine', + name: 'runEngine', + type: 'options', + default: 'skyvern-2.0', + options: [ + { + name: 'Skyvern 1.0', + value: 'skyvern-1.0', + }, + { + name: 'Skyvern 2.0', + value: 'skyvern-2.0', + }, + { + name: 'OpenAI CUA', + value: 'openai-cua', + }, + { + name: 'Anthropic CUA', + value: 'anthropic-cua', + } + ], + routing: { + request: { + body: { + engine: '={{$value}}', + }, + }, + }, + } ], displayOptions: { show: { resource: ['task'], + taskOperation: ['dispatch'], }, }, }, @@ -400,7 +399,6 @@ export class Skyvern implements INodeType { }, }, }, - // *** New property: optional webhook URL for Workflow dispatch *** { displayName: 'Webhook Callback URL', description: 'Optional URL that Skyvern will call when the workflow run finishes', @@ -417,7 +415,7 @@ export class Skyvern implements INodeType { routing: { request: { body: { - webhook_callback_url: '={{$value ? $value : undefined}}', + webhook_callback_url: '={{$value ? $value : null}}', }, }, }, diff --git a/integrations/n8n/package.json b/integrations/n8n/package.json index 36eb0505..b8aa713d 100644 --- a/integrations/n8n/package.json +++ b/integrations/n8n/package.json @@ -1,6 +1,6 @@ { "name": "n8n-nodes-skyvern", - "version": "0.0.4", + "version": "0.0.5", "description": "Skyvern Node for n8n", "keywords": [ "n8n-community-node-package"